Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to report AWT/Swing event queue length programmatically?

Ideally, the answer will be platform independent, but platform specific, particularly Oracle JVMs, are useful as well. The project that I'm working on is still running a version 6 JVM.

The particular need has to do with a GUI that is "freezing" from time to time. I'm well aware of doing on GUI work on the EDT. The program was working well on Windows, but after moving to Linux, these "strange" GUI issues began to happen. Actually, this issue has occurred on two applications, both after a Windows to Linux move. JVisualVM shows over 10 million java.awt.EventQueueItem objects. The suspicion is that the AWT queue is growing faster than it's being served on Linux, so the idea is to put an AWT queue length indicator on the app and see what it shows as the queue grows/shrinks.

A bit of Googling found this, but it does a linear scan of the queue. Maybe there's some better way?

like image 726
Greg Mattes Avatar asked Aug 09 '13 18:08

Greg Mattes


1 Answers

Interesting subject. I've investigated the EventQueue code a bit, and while I haven't solved your problem, I may have some useful pointers:

  1. Oracle's implementation of EventQueue doesn't keep a size variable, so unless you take over complete control of the EventQueue (see 3), there's no way you're going to do better than a linear scan of the queue when using Oracle's JRE.
  2. You can write you're own EventQueue (probably copy-pasting Oracle's implementation plus some tweaking** will be the easiest) and use EventQueue.push(EventQueue) to install your own implementation. All events in the queue will be transferred to your queue, so you can count them as they are posted to your queue. Unfortunately, this is still a linear scan, but at least now it's platform independent.
  3. Alternatively, you could install your own EventQueue implementation (see 2) as soon as possible after the original event queue has been created (do this in a static code block at the start of the class that contains your main method). Then, your implementation can count all events as they are posted and you don't have to scan the queue when you want to know the size. You'll just have to hope no one else pushes their own EventQueue on top of yours ;)

** Some tweaking: I haven't tried this, but I would strip all public/protected static code (everyone that references those methods/variables uses java.awt.EventQueue anyway, and so can you), add the size variable and update this variable in the following four methods: postEvent(AWTEvent, int), getNextEventPrivate(), getNextEvent(int) and removeSourceEvent(Object, boolean).

A big issue with this modification is the fact that the EventQueue makes some calls to AWT methods with default visibility (for example, Toolkit.getEventQueue() and Component.getAccessControlContext()), which you are not allowed to call since your implementation will be in a different package. You'll have to find a workaround for each case individually.

like image 115
Jelle Fresen Avatar answered Sep 21 '22 17:09

Jelle Fresen