jvm performance monitoring

I. tools

1. jps

check running jvm instances

jps -lvm

2. VisualVM (JVisualVM)

https://visualvm.github.io/ has latest tool. An alternative is the JVisualVM tool distributed with your JDK.

2.1 enable remote debug

Enable remote debugging, anonymous access

-Dcom.sun.management.jmxremote.port=8897 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=192.168.31.121

Enable remote debugging, password access

-Dcom.sun.management.jmxremote.port=8897 \
-Dcom.sun.management.jmxremote.password.file=jmx.passwd \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=192.168.31.121

Edit jmx.passwd file:

monitorRole good
controlRole bad

More documents available at: http://docs.oracle.com/javase/8/docs/technotes/guides/management/agent.html

3. jstatd

All-in-one script to start jstatd:

#!/bin/sh
set -x
policy=${HOME}/.jstatd.all.policy
[ -r ${policy} ] || cat >${policy} <<'POLICY'
grant codebase "file:${java.home}/../lib/tools.jar" {
  permission java.security.AllPermission;
};
POLICY

jstatd -J-Djava.security.policy=${policy}

With jstatd running, ‘jvisualvm’ can activate ‘Visual GC’ plugin.

4. jcmd

jcmd <PID> VM.command_line
jcmd <PID> VM.flags

5. jmap

jmap -dump:format=b,file=<name.hprof>
jmap -dump:live,file=<live_heap.bin>

For analyzing memory leaks just live objects are good enough.

II. Useful JVM flags

dump on OOME

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs/heapdump

native memory tracking

Enable native memory tracking by

-XX:NativeMemoryTracking=summary

or

-XX:NativeMemoryTracking=detail

Then issue the following command:

jcmd <pid> VM.native_memory baseline

and then

jcmd <pid> VM.native_memory detail.diff

III. Appendix

Execute runnable jar with following wrapper

#!/bin/bash
if [ $# -ne 1 ]; then
    echo "Usage: ${0} <path_to_jar>"
    exit 1
fi

ts=`date +%Y.%m.%d.%H.%M.%S`
logfile="console_${ts}.log"
set -x
java \
    -Dcom.sun.management.jmxremote.port=8897 \
    -Dcom.sun.management.jmxremote.password.file=jmx.passwd \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Djava.rmi.server.hostname=10.37.116.86 \
    -XX:+HeapDumpOnOutOfMemoryError \
    -XX:NativeMemoryTracking=detail \
    -jar $1 \
    >> ${logfile} 2>&1 \
    &
set +x
sleep 1
echo "console log written to ${logfile}"