7

理想情况下,答案将与平台无关,但特定于平台,尤其是 Oracle JVM,也很有用。我正在处理的项目仍在运行版本 6 JVM。

特别需要与不时“冻结”的 GUI 有关。我很清楚在 EDT 上做 GUI 工作。该程序在 Windows 上运行良好,但在迁移到 Linux 后,这些“奇怪”的 GUI 问题开始发生。实际上,这个问题已经发生在两个应用程序上,都是在从 Windows 迁移到 Linux 之后。JVisualVM 显示超过 1000 万个java.awt.EventQueueItem对象。怀疑是 AWT 队列的增长速度比它在 Linux 上的服务速度要快,因此我们的想法是在应用程序上放置一个 AWT 队列长度指示器,并查看它在队列增长/收缩时显示的内容。

用谷歌搜索找到了这个,但它对队列进行了线性扫描。也许有更好的方法?

4

1 回答 1

3

有趣的主题。我已经调查了 EventQueue 代码,虽然我还没有解决你的问题,但我可能有一些有用的指针:

  1. Oracle 的 EventQueue 实现不保留大小变量,因此除非您完全控制 EventQueue(请参阅 3),否则在使用 Oracle 的 JRE 时,没有比线性扫描队列更好的方法了。
  2. 您可以编写自己的 EventQueue(可能是复制粘贴 Oracle 的实现加上一些调整**将是最简单的)并用于EventQueue.push(EventQueue)安装您自己的实现。队列中的所有事件都将转移到您的队列中,因此您可以在它们发布到您的队列时对其进行计数。不幸的是,这仍然是线性扫描,但至少现在它是独立于平台的。
  3. 或者,您可以在创建原始事件队列后尽快安装您自己的 EventQueue 实现(参见 2)(在包含您的 main 方法的类开头的静态代码块中执行此操作)。然后,您的实现可以在发布所有事件时对其进行计数,并且在您想知道大小时不必扫描队列。您只需要希望没有其他人将自己的 EventQueue 推到您的之上;)

** 一些调整:我没有尝试过,但我会删除所有公共/受保护的静态代码(引用这些方法/变量的每个人都使用 java.awt.EventQueue,你也可以),添加大小变量并更新此变量有以下四种方法:postEvent(AWTEvent, int)getNextEventPrivate()和。getNextEvent(int)removeSourceEvent(Object, boolean)

此修改的一个大问题是 EventQueue 对具有默认可见性的 AWT 方法进行了一些调用(例如Toolkit.getEventQueue()Component.getAccessControlContext()),因为您的实现将在不同的包中,所以不允许您调用这些方法。您必须为每种情况单独找到解决方法。

于 2013-08-13T08:47:50.837 回答