@Brandon_Hurr An update:
The probable cause
Whenever ImageJ activates a window, it sets that window’s menu bar to the ImageJ MenuBar object. Historically, this was a fast way of keeping the same menu bar across multiple windows on OS X. However, it seems that with Oracle’s Java (i.e.: Java 7 and 8), there are now performance problems with doing this. In my profiling, I noticed the following call stack during the increasingly slow macro execution:
"AWT-EventQueue-0" #15 prio=6 os_prio=31 tid=0x0000000126901000 nid=0xf203 runnable [0x0000700001ffb000]
java.lang.Thread.State: RUNNABLE
at sun.lwawt.macosx.CMenuItem.nativeCreate(Native Method)
at sun.lwawt.macosx.CMenuItem.createModel(CMenuItem.java:63)
at sun.lwawt.macosx.CMenuComponent.<init>(CMenuComponent.java:40)
at sun.lwawt.macosx.CMenuItem.<init>(CMenuItem.java:40)
at sun.lwawt.macosx.LWCToolkit.createMenuItem(LWCToolkit.java:261)
at java.awt.MenuItem.addNotify(MenuItem.java:237)
- locked <0x00000005faab1308> (a java.awt.Component$AWTTreeLock)
at java.awt.Menu.addNotify(Menu.java:180)
- locked <0x00000005faab1308> (a java.awt.Component$AWTTreeLock)
at java.awt.Menu.addNotify(Menu.java:180)
- locked <0x00000005faab1308> (a java.awt.Component$AWTTreeLock)
at java.awt.MenuBar.addNotify(MenuBar.java:149)
- locked <0x00000005faab1308> (a java.awt.Component$AWTTreeLock)
at java.awt.Frame.setMenuBar(Frame.java:595)
- locked <0x00000005faab1308> (a java.awt.Component$AWTTreeLock)
at ij.ImageJ.windowActivated(ImageJ.java:609)
A temporary workaround
I pushed a branch which disables the menu syncing. Using that build of ImageJ 1.x, I’m seeing numbers in your macro as follows:
2912
861
2885
4906
2943
2890
2921
2930
904
2847
It seems a bit random still—but the increasingly huge delays are gone. Memory usage also seems very stable even after many runs.
Other slowness
Even with that build, behavior is still much worse when the ImageJ application does not have the focus. If you start the macro, then click over to another application, ImageJ’s window creation slows to a crawl. This might be a general issue with recent versions of OS X, and I vaguely recall someone in the community (@christlet?) mentioning a checkbox toggle for disabling this sort of behavior…
Further testing needed! Please help!
I think this discovery is great news, especially if others in the community can confirm that disabling the menu synchronization makes ImageJ usable again on OS X for medium-to-large-scale automated image analysis.
If you want to test for yourself, you can download the build I posted online (or build it yourself from the branch).
How to actually fix this
The tricky part is deciding how to actually fix this bug properly. While we could in theory report the issue to Oracle and wait for a fix… in practice, that fix would be a long time coming, if ever. Much better would be to stop doing things the way we are doing them. Possible alternatives:
-
Use JMenuBar instead of MenuBar, and sync menus the same way. This would need testing whether JMenuBar ends up having the same problem. I am guessing yes, but maybe not.
-
Use JMenuBar with a different menu sync strategy—very likely the com.apple.eawt.Application.setDefaultMenuBar method, now that it is available from Oracle Java on OS X. See SO #16175884 for details.
-
Use JDialog (or Dialog) instead of Frame for child windows. This would need to be done on a platform-specific basis, since it would work well on OS X but less well on Windows. Hence, it would not really be a tenable solution for ImageJ1, since ImageJ1 UI functionality typically extends Frame or Dialog directly, and thus it wouldn’t be possible to “swap” which kind of window implementation is used based on the platform. Again, see SO #16175884 for details.
@Wayne Your thoughts? I favor use of com.apple.eawt.Application.setDefaultMenuBar over the current menu syncing strategy—as long as the behavior of the approach is good enough (in 2012 it was too buggy, but supposedly those bugs are all fixed now).