March 8, 2015

Profiling in Java

I've recently started doing some manga translation again, but what that means is that I've tried to get my GMAO program running on my newer MacBook. Just trying to run the OSX app that I packaged a few years back brought up a dialog box asking me to install the 1.6 JRE. I don't really want to do that, we're in the 21st century now, and I want to run Java 1.8. So I downloaded that JRE. Still, I get the message. It turns out that the type of launcher I use (info.plist XML or whatever) is the style that Apple supported which only works with their JRE, which is only available to 1.6. And is more or less deprecated now.

So I found out that if I download the JDK (and just the JRE) I get the command line tools, and then I can pretty easily start up GMAO from the command line from the .app. Which still is far from ideal, so I guess I need to re-package it to use the new launcher format. First though, since I can at least run GMAO on the new laptop, I started to do some translation. Great.

Except, it takes about three minutes (wall clock minutes) to load a new image. That is terrible. It used to take on the order of seconds, if that. So I guess there is something in the APIs that have changed to make whatever I'm doing super slow - I know my code doesn't do anything that should take that long. So I'll have to track that down.

I installed Eclipse and copied my code over. Wow, over 800 warnings. Mostly about non-parameterized types. I should probably fix those. I'm able to compile under Java 1.8 though, so that is good.

Where is all that time going when I load an image? Let's try to profiling. So, I try to use jvisualvm. I can look at the heap and stuff, but CPU profiling is not supported: "failed to create jmx connection to target application". I tried many things, but I just couldn't get things working. I enabled some logging and a net connection was timing out.

RMI uses two ports for communication, which is pretty dumb if you are behind a firewall. Anyway, I don't think that was the problem here, I think it was having trouble finding the host to get the RMI information from.

Finally I found some java options that I could use to get the connection to work. On the JVM running the app I want to profile:

java -Xmx2048m -Djava.rmi.server.hostname=localhost -classpath $CP com.FuguTabetai.GMAO.GMAOGUI
I was able to start up jvisualvm and connect to the JVM that way. The profiling was helpful, but didn't get me as far as I wanted. By the way, if you are on OSX and want to start jvisualvm you can just use jvisualvm, but to run Java Mission Control I had to find out where that binary was:
find /Library/Java -name jmc
/Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/lib/missioncontrol/Java Mission
Here are some other interesting notes. Using the HPROF option just showed me some garbage, it isn't accurate. See this excellent post for more information about that. This post was super helpful in tracking down my connection problems with JMX. Google might have a nice lightweight java profiler but I haven't read that yet. This stackoverflow post pointed me in the right direction for finding the critical java.rmi.server.hostname parameter (and maybe I'll probably need to look more into how to do Java app bundles in this brave new Java 1.8 world.


Provide your email address when commenting and Gravatar will provide general portable avatars, and if you haven't signed up with them, a cute procedural avatar with their implementation of Shamus Young's Wavatars.

Comments have now been turned off for this post