Mac Java Speed Issues

Been using ImageJ for quite a few years on my Macs and up until last year sometime things were usually running very smoothly. A lot of macros that I use are what I call semi-automatic in that they cannot run in batch mode and often require user input to complete successfully. I am often processing 100s of images this way.

What’s been happening lately is that out of batch mode things gradually slow down over time. I do know that out of batch mode things run much slower than in batch mode, but it seems like there is a lot more to it, because before upgrading to Java 7/8 and Yosemite/El Capitan things used to be much better and faster.

I’ve written a simple script that takes an image, processes it with a color threshold and then repeats this 5 times. It has a lot of duplications and closes all but the initial image every loop and spits out the time it took for that loop.

When running in batch mode, the time is really consistent at about 70 ms, but out of batch mode, it takes a long time and the time increases. I only ran the loopt five times because if I run it much more than that, it bogs FIJI all the way down and I can’t even kill the macro easily. Menus take a while to refresh… it’s a mess.

I know that Chris in his ImageJ talk this year mentioned that there were Mac issues and I think I’m hitting my head against them. This does not happen on my work laptop (which is generally too slow for image analysis).

I’m running this in FIJI with ImageJ (daily) and ImageJ 1.50d and the results are fairly consistent.

In Batch mode (in ms):
66
69
72
66
68

Not in Batch mode (in ms):
12047
24985
37997
48017
68231

I am running Java 8, update 60 and have tried it with update 66. Similar results. My Mac is an iMac with 4-core i7 at 3.2 Ghz. It is not a “slow” computer.

My work windows laptop is a mobile i5 and I’m unsure of the speed. It has Java 1.7.0_71 32 bit ImageJ 1.50d
batchmode
452
250
109
125
140

batchmode off
679
613
711
549
563

//load lena.jpg

lena = getTitle();

selectWindow(lena);

setBatchMode(true);

for (z=0; z<5; z++) {
	startTime = getTime();
	
	run("Duplicate...", "title=painted");
	
	run("Duplicate...", "title=colorthresholdsomething");
	selectWindow("colorthresholdsomething");
	
	// Color Thresholder 2.0.0-rc-39/1.50b
	// Autogenerated macro, single images only!
	min=newArray(3);
	max=newArray(3);
	filter=newArray(3);
	a=getTitle();
	run("RGB Stack");
	run("Convert Stack to Images");
	selectWindow("Red");
	rename("0");
	selectWindow("Green");
	rename("1");
	selectWindow("Blue");
	rename("2");
	min[0]=0;
	max[0]=23;
	filter[0]="pass";
	min[1]=0;
	max[1]=18;
	filter[1]="pass";
	min[2]=126;
	max[2]=255;
	filter[2]="pass";
	for (i=0;i<3;i++){
	  selectWindow(""+i);
	  setThreshold(min[i], max[i]);
	  run("Convert to Mask");
	  if (filter[i]=="stop")  run("Invert");
	}
	imageCalculator("AND create", "0","1");
	imageCalculator("AND create", "Result of 0","2");
	for (i=0;i<3;i++){
	  selectWindow(""+i);
	  close();
	}
	selectWindow("Result of 0");
	close();
	selectWindow("Result of Result of 0");
	rename(a);
	// Colour Thresholding-------------


	run("Convert to Mask");
	
	invertedLUT = is("Inverting LUT");
	if (invertedLUT == 1) {
		run("Invert LUT");
		run("Invert");
	}
	
	run("Options...", "iterations=8 count=1 do=Dilate");
	run("Fill Holes");

	run("Create Selection");
	run("Close");
	selectWindow("painted");
	run("Restore Selection");
	setForegroundColor(0, 0, 0);
	run("Fill", "slice");
	run("Select None");
	run("Close");
	
	endTime = getTime();
	timeDiff = endTime - startTime;

	print(timeDiff);
}
1 Like

After some further digging, it looks like it is related to the use of integrated graphics and a slow implementation of drawing in Java.

http://comments.gmane.org/gmane.comp.java.openjdk.macosx-port.devel/6869

This says the bug was fixed (mainly for netbeans), but I think it’s not according to the gmane forum:
https://bugs.openjdk.java.net/browse/JDK-8029253

This seems related because I’m using discrete graphics only.
https://bugs.openjdk.java.net/browse/JDK-8041900

Is the current thinking that this is not fixable until Java is fixed on Macs? @ctrueden

3 Likes

@Brandon_Hurr Thank you for the detailed analysis and measurements.

There is not really any “current thinking” per se. I haven’t had time to dig into why ImageJ grinds to a halt with Java 8 and/or El Capitan. At this point you have done more research into it than I have.

If it is a problem with Oracle Java itself, then yeah, it is pretty tough to fix before Java itself is fixed. But I know next to nothing about the cause—maybe we could work around the problem somehow.

My current understanding (not fully substantiated with thorough research and testing) is that there are actually multiple scenarios here with distinct problems:

  • Some systems are using older versions of Java 8 which have a severe painting issue which has since been fixed. But there are multiple reasons someone might still be running an older version of Java 8. For example, the ImageJ Launcher does not automatically pick the latest installed version of Java 8—just a version of Java 8. Typically it picks the first one it finds, actually, which may often be the oldest installed version. For now, the easiest solution there is to uninstall older versions of Java 8, keeping only the newest.

  • The “general slowness” problem is because Oracle Java 8 is still slower graphically than Apple Java 6 is (which one of your links above points out). Not much you can do about that, other than switch back to Apple Java 6 for the time being.

  • The “grinding to a halt” problem is reported to happen with the latest Java 8 (including 1.8.0_60 and 1.8.0_66) and is likely quite distinct from the painting issues of older Java 8 versions.

  • The “Dock icon malfunctioning” problem is also reported to happen with the latest Java 8. I have been unable to reproduce any Dock-related issues on my El Capitan machine with Java 1.8.0_66, although multiple users have reported it [1, 2].

When I mentioned “issues with OS X” at the conference, I actually had not yet heard about the “grinding to a halt” or “Dock icon malfunctioning” problems—I referred more to the general transition of OS X from Apple Java to Oracle Java, how it leaves behind OS X 10.6 “Snow Leopard” and earlier, and how the ImageJ Launcher needed to get smarter to support both Java flavors (and still doesn’t fully support them both in certain ways). See 2015-06-15 - Major updates in the works and 2015-06-17 - Better behavior on OS X for some additional details.

See also:

Sorry I don’t have any better news to report yet.

1 Like

@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).

3 Likes

On Macs, the latest ImageJ daily build (1.50e21) does not set the default ImageJ menu bar when macros are running. The test macro now runs much faster on both Java 6 and Java 8, but it runs four times faster on Java 6 than it does on Java 8. The default menu bar is always set in the new Window.Manager.setDefaultMenuBar() method, so it should be easy to switch to using com.apple.eawt.Application.setDefaultMenuBar.

1 Like

Hi, indeed I mentioned this a while ago. I found that keeping ImageJ from using the “App Nap” feature (that appeared in Mavericks 10.9) allows background processing to be faster. Right-click (or ctrl-click) your ImageJ.app or Fiji.app and choose “Get Info”, then check the “Prevent App Nap” box.

Happy to bring my very small piece to a better performance of ImageJ on OSX!

3 Likes

@ctrueden, yes, that makes a huge difference when the window is in focus. The windows are being drawn at a similar rate to that of my windows machine.
On my machine, with batchmode ON
179
144
81
91
76
batchmode OFF
4948
2950
2975
2931
2970

Much better (2-5 s per “image”) and doesn’t appear to accumulate slow down. I presume the rest of the difference is due to Java7/8 being slower and batchmode being faster. Great find.

@christlet, at one point I had globally disabled appnap to prevent that slowing down running imagej in the background but it didn’t seem to make much of a difference. :confused: I’ll give it a try again sometime.

About App Nap

Firstly, on El Capitan, it seems that the “Disable App Nap” checkbox is missing from the Info dialog of ImageJ.app.

I played around with disabling App Nap by editing ImageJ’s Info.plist, which would be better anyway since then it would be disabled for all users by default. I tried with both the current Info.plist shipped with Fiji, as well as the new experimental JavaFX-based application bundle, which has a quite different Info.plist.

The two possible keys seem to be LSAppNapIsDisabled and NSAppSleepDisabled. I tried setting them both:

<key>LSAppNapIsDisabled</key>
<true/>
<key>NSAppSleepDisabled</key>
<true/>

But they seem to have no effect on behavior. Activity Monitor shows ImageJ as “No” in the App Nap column in every case—but the execution still slows to a crawl when ImageJ is out of focus.

Further ideas welcome.

About graphics

In all cases, Activity Monitor also lists “Yes” for “Requires High Perf Graphics” even if NSSupportsAutomaticGraphicsSwitching is set to true. In the JavaFX bundle case, this is apparently a limitation of the JavaFX application bundler.

About Wayne’s fix

@Wayne Thanks for the fix in the daily build. I guess it will be adequate for most people in most situations, although I still fear eventual performance problems and/or memory leaks when working with ImageJ over long periods of time, opening and closing many windows over time. Maybe it is good enough for now…

Thank you. I am afraid a switchover would not be entirely trivial, since Application.setDefaultMenuBar requires a JMenuBar. However, the good news is that even AWT Frame (i.e.: not only Swing JFrame) windows benefit from the default JMenuBar as long as they have no MenuBar or JMenuBar of their own attached. So it will be possible for ImageJ2 to patch ImageJ1 along these lines, overriding WindowManager.setDefaultMenuBar to do nothing on OS X, in favor of inheriting a JMenuBar concocted to look exactly like ImageJ1’s normal MenuBar. We’ll still need to test the time and memory performance of creating many windows in this way, though. I filed imagej/imagej-legacy#130 so we don’t forget.

Hey all, I was just wondering if this has been resolved.

I remember reading through most of this thread a few months ago and switch to using Java 6 through the command line. Still, it always takes forever to launch and I cant drag files over the icon to use the importer.

Is there anything else I can do to fix the performance issue when using Java 8?

Thanks!

@dprotter I have not invested any time on this issue since my post above. However, there have been a few new revisions of Java 8. You could try testing with the latest one and see whether it still suffers from these speed issues.

If the multiple window creation slowdown continues to be a showstopper issue for people, we can investigating fixing imagej/imagej-legacy#130. Regarding the App Nap and graphics-related issues, I know of no fix or workaround, unfortunately.

I’ve had pretty good luck with the speed of things since Wayne introduced the fix. I’m running 1.8.0_66 right now (there are newer Java versions) and I get pretty good results with the macro I listed above. If anything, it has improved slightly to an average closer to 65 ms per “test run”. What’s interesting is that it always starts out poor in a new session, but improves rapidly, as the operations are performed again and again. This is with FIJI 2.0.0-rc-43/1.50h35 on OSX 10.11.3.

1 Like

So I’ve upgraded again to the highest level of imageJ, and tried running it using Java8. It still ran slow.

Unfortunately, upgrading broke the java6 launching script I pulled off the forum somewhere (pasted below). I’m using El Capitan, and I’ve got a healthy 16 GB of memory.

export IJ_HOME=/Applications/Fiji.app
J6/bin/($IJ_HOME/Contents/MacOS/ImageJ-macosx --dry-run | perl -pe ‘s/ -Djava.ext.dirs=.*? -D/ -D/’)

And the error it threw:
java.lang.UnsupportedClassVersionError: net/imagej/Main : Unsupported major.minor version 52.0

In any case there is clearly a problem switching from window to window. When I go to swap between windows the menu bar disappears for a few seconds. I cant do anything until it reappears, including using Shift-R to repeat previous commands.

I was wondering if this behavior could have something to do with the fact that El Capitan uses compressed memory. Fiji always seems to have at least some information stored in compressed memory, even when I’m actively using the application.

Basically, the time it takes to switch windows has made Fiji almost unusable for me. Sometimes I end up waiting ~8 seconds every time I need to switch windows, which adds a huge amount of time to my manual manipulations of my images.

Any help would be greatly appreciated, and rewarded with beer if you live near Boulder, CO.

1 Like

I can confirm that pass to El Capitan and using Java 8 Fiji is really really run slow and many times my own jython scripts and java plugins do not work at all.

This is starting to be a big issue at my institure since some users after updating their Mac to El Capitan Fiji starting to go really slow and some plugin do not work at all.

Thank you for your attention,
kind regards
Emanuele

1 Like

I see what @emartini and @dprotter are talking about. If you are in full manual mode sometimes when you switch windows the menu bar is blank except for the Apple and Fiji (or ImageJ) menu and you have to wait for it to appear for it to use the menus at all. Sometimes this can take many seconds to happen. There have been a few instances when it never appeared for me.

open(); //lena.png

for (i=0; i<99; i++) {
	run("Duplicate...", " ");
}

I click around on various windows including the script window. The first time I did it, it very quickly (< 20 clicks) started doing this severely. Took 5 seconds for the menu to appear. I closed FIJI and reran it and have clicked on more than 50 windows and it’s slower than at boot, but not awful (< 1 s).

@ctrueden, how did you debug the other thing previously to know what it was spending time on?

Running Fiji ImageJ 2.0.0-rc-43/1.51a2 with Java 1.8.0_77 (JDK installation) on OS X 10.11.4 (15E65)

Edit: added macro code for lena image, and system info

3 Likes

I’m seeing the same behaviour; long delays before the menu appears when switching between windows… very poor performance (unusably so). Running the latest Java (Java 8 update 91) and Fiji (ImageJ) version 2.0.0-rc-43/1.51a build 49b667f9aa on OS X 10.11.5 (15F34).

Any advice or updates would be most appreciated!

That is not the latest version of ImageJ2. It should be 2.0.0-rc-49 (as of this writing). You need to turn on the Java-8 update site. See this guide for details.

That said, updating to the latest will not (yet) fix any of those performance problems. But if/when we do identify ways to improve performance, you will want to have the Java-8 update site turned on in order to receive them.

@Brandon_Hurr Sorry I never replied regarding how to profile the code. You can use a tool called JVisualVM, which comes with the JDK. Or you can just take repeated stack traces as described here. (I think the latter is what I did for testing before.)

@ctrueden, thanks I’ll look at it again when I get a chance. The window menu refresh thing has popped up again for me a few times. It’s much better than it was before, but still problematic. Usually I just close FIJI and reopen and continue working on my script when things bog down. It suggests some sort of cumulative effect when there are lots of windows open. I’ll let people know if I can find anything. If others can also look at things when their system slows down, that would be great as a validation that we’re all having the same problem.

2 Likes

Okay, I’ve selected the Java 8 update site, updated and now I’m running version 2.0.0-rc-49/1.51a build e01a259e5d on java version "1.8.0_65"
Java™ SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot™ 64-Bit Server VM (build 25.65-b01, mixed mode).

I’ve allocated 24 Gb of RAM to Fiji, so there should be no memory constraints, and it doesn’t appear to be swapping nor does the memory usage appear to be going up. When I open an .lei file (Leica confocal data format), the BioImport dialogue opens fine, but when I click ‘okay’ it says “Reading file header” and Fiji seems to have one CPU stuck at 100% for 7 minutes (this is a task that would normally take a couple of seconds at most).

It does eventually open the window with the stacks in the experiment available for selection, and I can open them, but the massive delay makes this effectively unusable.

You can determine where this slowdown is happening by following these directions.

I also suggest bringing this to the attention of the Bio-Formats team, as this might be a bug in Bio-Formats.

Try upgrading to the latest ImageJ daily build (1.51e42) and enabling “Don’t set Mac menu bar” in the Edit>Options>Misc dialog box. When this option is enabled, ImageJ does not set the ImageJ menu bar when activating image windows. This may prevent long delays when running Java 8 on OS X but the menu bar at the top of the screen will be blank except for the “ImageJ” menu. To recover the full menu bar, click on the “ImageJ” window or press return, the shortcut for the Window>Main Window command. To make this option permanent, add

run("Misc...", "divide=Infinity don't");

to the Edit>Options>Startup dialog.

1 Like