Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Tips February 2006
Get rid of your performance problems and memory leaks!
Get rid of your performance problems and memory leaks!
Back to newsletter 063 contents
JSE 5.0 Trouble-Shooting and Diagnostic Guide (Page last updated June 2005, Added 2006-02-27, Author Sun, Publisher Sun). Tips:
- jstack, jinfo, and jmap command line utilities are included in the JDK release for Solaris and Linux only.
- jstack, jinfo, jmap and jdb can obtain info from running JVMs and from core files generated from JVM crashes.
- jstat and jconsole enable the monitoring of many aspects of a running JVM.
- The HPROF profiler is a simple profiler included in the JDK, capable of presenting CPU usage, heap allocation statistics, contention profiles, heap dumps, states of all the monitors and threads. HPROF can be useful when analyzing performance, lock contention, memory leaks, and other issues.
- The Heap Analysis Tool (HAT) is a useful for diagnosing unnecessary object retention (or memory leaks). It can be used to browse an object dump, view all reachable objects in the heap, and understand which references are keeping an object alive.
- jinfo prints the system properties and the command line flags that were used to start the VM, e.g. with jinfo <pid|core>.
- jmap prints memory related statistics for a running VM or core file; by default it prints the list of shared objects loaded (the output is similar to the Solaris pmap utility).
- jmap -heap prints GC algorithm specific information: the name and details of the GC algorithm in use; the heap configuration; and a heap usage summary (total capacity, in-use and available free memory for each generation).
- jmap -histo provides a class-wise histogram of the heap: for each class, it prints the number of objects, memory size in bytes, and fully qualified class name.
- If an application loads or generates too many classes then it is possible it will abort with an OutOfMemoryError. The specific error is: "Exception in thread XXXX java.lang.OutOfMemoryError: PermGen space".
- jmap -permstat provides details on classloader statistics. For each classloader instance six fields are printed: class loader object hexadecimal address; number of classes loaded; total approximate number of bytes used class by meta-data; hexadecimal address of the parent class loader; GCable (dead indicates classloader will be garbage collected); the class name of this class loader.
- jstack prints a stack trace of all threads - similar to using the thread dump handler (i.e. Cntrl-\ or kill -QUIT or Thread.getAllStackTraces).
- Thread states in a thread stack dump can be one of the following: UNINTIALIZED Thread is not created; NEW Thread has been created but it has not started running yet; IN_NATIVE Thread is running native code; IN_VM Thread is running VM code; IN_JAVA Thread is running (either interpreted or compiled) Java code; BLOCKED Thread is blocked; ..._TRANS If you see any of the states followed by "_TRANS", it means the thread is changing to a different state.
- jstack stack lines have the format <Fully qualified class name>.<Method name> @bc=<Byte code index>, line=<Source line number> (Method compiled/interpreted?), e.g. "java.lang.Thread.run() @bci=11, line=595 (Interpreted frame)"
- jstack -m will print a (mixed) stack including native stack frames in addition to the java stack. (Native frames are the C/C++ frames associated with VM code, and JNI/native code; you may need to pipe the output through the c++filt to demangle C++ mangled symbol names.)
- jconsole can attach to any application that is started with the JMX agent. The -Dcom.sun.management.jmxremote option is the system property which enables the JMX agent.
- The jconsole Summary panel lists: Uptime: how long the JVM has been running; Total compile time: the amount of time spent in runtime compilation; Process CPU time: the total amount of CPU time consumed by the JVM.
- The jconsole Memory panel lists: Current heap size: Number of Kbytes currently occupied by the heap; Committed memory: Total amount of memory allocated for use by the heap; Maximum heap size: Maximum number of Kbytes occupied by the heap; Objects pending for finalization: Number of objects pending for finalization; Garbage collector information: Information on GC, including the garbage collector names, number of collections performed, and total time spent performing GC.
- The jconsole Threads panel lists: Current number of live daemon threads plus non-daemon threads; Highest number of live threads since JVM started; Current number of live daemon threads; Total number of threads started since the JVM started (including daemon, non-daemon, and terminated).
- The jconsole Classes panel lists: Number of classes currently loaded into memory; Total number of classes loaded into memory since the JVM started, including those subsequently unloaded; Number of classes unloaded from memory since the JVM started.
- The jconsole Operating System panel lists: Amount of random-access memory (RAM) that the machine has; Amount of free RAM the machine has; Amount of virtual memory guaranteed to be available to the running process.
- jps lists accessible JVMs on the local system (and prints other parameters of teh JVM depending on options used); also for remote systems that are running jstatd.
- jstat uses built-in HotSpot VM instrumentation to provide information on performance and resource consumption of running applications, in particular issues related to heap sizing and garbage collection.
- jstat options prints statistics on: class loaders, the HotSpot compiler, and garbage collected heap stats and capacities by generations.
- visualgc provides a graphical view of the garbage collection system. As with jstat it uses the built-in instrumentation of the HotSpot VM.
- HPROF is a simple dynamically-linked library profiler agent shipped with JDK 5.0. HPROF is capable of presenting CPU usage, heap allocation statistics and monitor contention profiles. It can also report complete heap dumps and states of all the monitors and threads.
- HPROF is invoked with "java -agentlib:hprof <ToBeProfiledClass>"; use "java -agentlib:hprof=help" to get a listing of all the available HPROF options
- For HPROF cpu=samples is the recommended method profiling option; heap=sites is the recommended object memory profiling option.
- HPROF heap dump output is complex; the article covers some types of entry but recommends using HAT or other tool (HP have one too) to visualize the information.
- HAT (available from http://hat.dev.java.net) is capable of reading HPROF output in order to identify object roots that may be causing unintentional object retention.
- The "-XX:OnError=" option enables other operating system processes to be run if the JVM terminates on a fatal hotspot error, for example "java -XX:OnError="gcore %p" ..." to create a core dump on Solaris; or "java -XX:OnError="userdump.exe %p" MyApplication on Windows (or configure the Windows system to use Dr Watson to automatically create a crash dump).
- [Article describes using Solaris dbx debugger to operate on a JVM].
- [Article describes using Solaris/Linix jdb debugger to operate on a running JVM or core file].
- A stack dump is printed to stdout if the ctrl-break handler is executed (normally kill -QUIT or cntrl-\ on Unix or cntrl-brk on Windows). The ctrl-break handler also executes a deadlock detection algorithm: If any deadlocks are detected then it prints out additional information on each deadlocked thread.
- A thread header line in a ctrl-break handler stack dump reads as follows: "<thread name>" [daemon] prio=<java_priority> tid=<address of the thread structure in memory> nid=<id of the native thread> <Thread state> [<address range ? this is an estimate of the valid stack region for the thread.>], e.g."Java2D Disposer" daemon prio=10 tid=0x002007d8 nid=0xb in Object.wait() [0xf0701000..0xf07019b8].
- The possible thread states in the output from a ctrl-break handler stack dump are: allocated; initialized; runnable; waiting for monitor entry; waiting on condition; in Object.wait(); sleeping.
- If the ctrl-break handler deadlock detector identifies a deadlock, then after the thread dump the information is printed starting with the line "Found one Java-level deadlock:"
- Information about GCs can be obtained using the options -verbose:gc -XX:+PrintGCDetails and -XX:+PrintGCTimeStamp.
- The -verbose:gc option can be dynamically enabled at runtime using the management API or JVM TI or using the jconsole tool.
- The -Xcheck:jni option makes the VM do additional validation on the arguments passed to JNI functions. When an invalid argument is detected, the VM prints a "FATAL ERROR in native method:" message, prints the stack trace of the offending thread, and aborts the VM. (Also possible that the message "Warning: Calling other JNI functions in the scope of Get/ReleasePrimitiveArrayCritical or Get/ReleaseStringCritical" may be printed).
- [Article lists useful operating system tools and their use in section 1.15 - Solaris: cputrack, cpustat, c++filt, dbx, dtrace, libumem, iostat, netstat, mdb, pfiles, pldd, pmap, prun, prstat, psig, pstack, pstop, ps, ptree, sar, truss, vmstat, gcore; Linux: ltrace, mtrace, muntrace, pmap, pstack, strace, top, vmstat, gdb; Windows: windbg, dumpchk, userdump].
- You can use the java.lang.management package to implement additional management and monitoring; it covers interfaces for the following systems: class loading; compilation; garbage collection; memory manager; runtime; threads.
- The Sun implementation of 5.0 includes platform extensions in the com.sun.management package (see http://java.sun.com/j2se/1.5.0/docs/guide/management/extension/index.html). The platform extensions include a management interface to obtain detailed statistics from garbage collectors and additional memory statistics from the operating system.
- The java.lang.instument package (http://java.sun.com/j2se/1.5.0/docs/api/index.html) provides services that allow Java programming language agents to instrument programs running on the JVM, for both load-time and dynamic instrumentation.
- java.lang.Thread.getAllStackTraces returns a map of stack traces for all live threads.
- java.lang.Thread.getState that returns the thread state; states are defined by the java.lang.Thread.State enumeration.
- OutOfMemoryError are now classified: heap space (increase mx); permgen space (increase perm space size); operating system space (increase RAM/swap); in all cases an alternative is to reduce memory requirements; any OOME could be from unintentional object retention (an object leak).
- "Exception in thread "main" java.lang.OutOfMemoryError: Java heap space" signifies not enough space available to create another object; either mx needs increasing or you have unintentional object retention (an object leak).
- "Exception in thread "main" java.lang.OutOfMemoryError: PermGen space" signifies too many classes loaded or being generated; or the String.intern table is too big. Increase using the -XX:MaxPermSize option.
- "Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit" signifies not enough space available to create another array; either mx needs increasing or you have unintentional object retention (an object leak).
- "Exception in thread "main" java.lang.OutOfMemoryError: request <size> bytes for <reason>. Out of swap space?" signifies either a memory leak of some sort, or more likely you ran out of available operating system memory.
- "Exception in thread "main" java.lang.OutOfMemoryError: <reason>" followed by "<stack trace>(Native method)" signifies Note that this is where the top element in the stack trace is a native method; either a memory leak of some sort, or more likely you ran out of available operating system memory.
- If you get a crash instead of an OutOfMemoryError, this is likely to be because a JNI level function used the NULL returned from a malloc call as a valid memory pointer. This indicates either a memory leak of some sort, or more likely you ran out of available operating system memory.
- If a class has a finalize method then objects of that type do not have their space reclaimed at garbage collection time. Instead after garbage collection the objects are queued for finalization which occurs sometime later.
- In the Sun JVM implementation finalizers are executed by a daemon thread that services the finalization queue. If the finalizer thread cannot keep up with the finalization queue then it is possible that the java heap will fill up and OutOfMemoryError will be thrown.
- jconsole can be used to monitor the number of objects that are pending finalization. (excessive use of finalizers can be the cause of OutOfMemoryError). In jconsole the pending finalization count is reported in the memory statistics on the "Summary" tab pane. The count is approximate but it can be used to characterize an application and understand if it relies a lot on finalization.
- Diagnosing leaks in Java Language code can be a difficult task, it is suggested that you use a profiler. Using HAT you would use java -agentlib:hprof=file=dump.hprof,format=b <Application>
- [A few considerations of using HAT to identify unintentional object retention are discussed, including comparing between two dumps].
- Anyone writing a JNI library would probably be wise to create some kind of localized way to make sure your library doesn't leak memory using a simple wrapper approach. [Article provides an example in section 2.1.3].
- libumem can be used to diagnose a native memory leak in Solaris.
- [Article explains the format of a hot spot crash log, see 2.2]
- To detect the cause of looping, get one or more thread dumps, that is usually sufficient to see where the execution locus is.
- If the VM does not respond to a Ctrl-\ this may suggest a possible VM bug rather than an issue with application or library code. In this case use jstack with the -m option to get a thread stack for all threads.
- In J2SE 5.0 deadlock detection works only with locks that are obtained using the synchronized keyword. This means that deadlocks that arise through the use of the java.util.concurrency package are not detected.
- [Article explains how to configure Dr Watson on Windows to get dumps on crashing, section 3.2.4].
Back to newsletter 063 contents
Last Updated: 2017-10-01
Copyright © 2000-2017 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us