How to programmatically report the AWT / Swing queue duration?

Ideally, the answer will be platform independent, but platform specific, especially Oracle JVMs, are useful. In the project I'm working on, the JVM version 6 is still working.

A particular need is related to the graphical interface, which is "frozen" from time to time. I know well how to work with GUI on EDT. The program worked well on Windows, but after switching to Linux, these "strange" GUI problems started to happen. In fact, this problem occurred in two applications, as after the transition of Windows to Linux. JVisualVM shows over 10 million java.awt.EventQueueItem objects. The suspicion is that the AWT queue grows faster than on Linux, so the idea is to add an AWT queue length indicator to the application and see what it shows when the queue grows / shrinks.

A little googling found this one , but it does a linear scan of the queue. Maybe there is a better way?

+6
source share
1 answer

An interesting subject. I was looking for EventQueue code a bit, and until I solved your problem, I might have some useful pointers:

  • The implementation of the Oracle EventQueue does not preserve the size variable, therefore, unless you take full control of the EventQueue (see 3), you cannot do this better than a linear queue scan using the Oracle JRE.
  • You can write your own EventQueue (maybe copy the Oracle implementation, as well as some setup ** will be the easiest) and use EventQueue.push(EventQueue) to set your own implementation. All events in the queue will be transferred to your queue, so you can count them when they are sent to the queue. Unfortunately, this is still a linear scan, but at least now it is platform independent.
  • Alternatively, you can set your own implementation of EventQueue (see 2) as soon as possible after creating the original event queue (do this in the static block of code at the beginning of the class that contains your main method). Then your implementation can count all events as they are published, and you do not need to scan the queue when you want to know the size. You just need to hope that no one else pushes your own EventQueue on top of you;)

** Some tweak: I have not tried this, but I would share all the public / protected static code (everyone who refers to these methods / variables still use java.awt.EventQueue, and you can too) add a size variable and update this variable in the following four methods: postEvent(AWTEvent, int) , getNextEventPrivate() , getNextEvent(int) and removeSourceEvent(Object, boolean) .

The big problem with this modification is that EventQueue calls some AWT method calls with default visibility (e.g. Toolkit.getEventQueue() and Component.getAccessControlContext() ), which you cannot call, since your implementation will be a different package . You will need to find a workaround for each case individually.

+3
source

Source: https://habr.com/ru/post/951414/


All Articles