Setting up a test Java process to profile.
1. From the terminal: cd /Developer/Examples/Java/JFC/Java2D/
2. From the terminal: java -jar Java2D.jar &
3. After the process starts it should indicate the pid (in this example it is 5510)
4. You can also use jps to discover the pid: jps -l (then look for the Java2D.jar)
Fixing jmap
If you type jmap
attach: task_for_pid(5510) failed (5)
Error attaching to process: Error attaching to process, or no such process
To fix this, do a sudo, such as sudo jmap
Debugger attached successfully.
Server compiler detected.
JVM version is 1.6.0_05-b13-52
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 88080384 (84.0MB)
NewSize = 2686976 (2.5625MB)
MaxNewSize = -65536 (-0.0625MB)
OldSize = 5439488 (5.1875MB)
NewRatio = 2
SurvivorRatio = 6
PermSize = 21757952 (20.75MB)
MaxPermSize = 88080384 (84.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 10551296 (10.0625MB)
used = 4592152 (4.379417419433594MB)
free = 5959144 (5.683082580566406MB)
43.52216069002329% used
At this point it looks like it is working, however the file dump doesn't work.
Fixing jhat
When running jhat on the hump dump, you get the following error:
Eliminating duplicate references.....................
Snapshot resolved.
Exception in thread "main" java.lang.RuntimeException: java.lang.NullPointerException
at com.sun.tools.hat.internal.oql.OQLEngine.init(OQLEngine.java:277)
at com.sun.tools.hat.internal.oql.OQLEngine.
at com.sun.tools.hat.internal.server.QueryListener.setModel(QueryListener.java:59)
at com.sun.tools.hat.Main.main(Main.java:189)
Caused by: java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.tools.hat.internal.oql.OQLEngine.init(OQLEngine.java:256)
... 3 more
It took me a little hunting to uncover the issue. It turns out that jhat uses the Java 6 js engine. If you go to the terminal again and run: jrunscript , it indicates that the script engine for language js can not be found. On the mac, if you execute: jrunscript -q, which provides a listing of script engines you'll see:
Language AppleScript 2.0.1 implemention "AppleScriptEngine" 1.0
Thank you apple!
As a side note if you actually wanted to run AppleScript as a shell, type jrunscript -l AppleScript
Let's get to fixing the issue
- Download JSR-223's engines https://scripting.dev.java.net/files/documents/4957/37593/jsr223-engines.zip
- Download Rhino http://www.mozilla.org/rhino/download.html
- Copy jsr223-engines/javascript/build/js-engine.jar to /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/ext/
- Copy rhino1_7R1/js.jar to /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/ext/
now jrunscript -q should look like this:
Language EmbeddedECMAScript 1.6 implemention "Mozilla Rhino" 1.6 release 2
Language AppleScript 2.0.1 implemention "AppleScriptEngine" 1.0
Language ECMAScript 1.6 implemention "Mozilla Rhino" 1.6R7
... and jrunscript will put you in a js shell.
... and jhat heap.out now works! Point your browser at http://localhost:7000 and object browse!
Also something I didn't realize until I was preparing for this post... jmap worked for the console dump if I sudo'd the command. However it would not do a file dump. I did the file dump using jconsole and jmx. Now that the scripting issue is fixed, jmap is improved in the following manner:
- if you type jmap
, it now prompts you for your admin password (instead of just failing) - jmap -dump:live,format=b.file=heap.out 5510 now works
It makes me wonder what else wasn't working! Happy Coding!