Showing posts with label garbage collection. Show all posts
Showing posts with label garbage collection. Show all posts

Thursday, August 12, 2010

Java Monitoring Tools

JDK 6.0 comes bundled with a number of handy, but often overlooked, utilities to monitor, manage and troubleshoot Java applications. They can be found in the bin directory of your installation. Here are a few of them explained:

1) jps - report java process status
This command prints information about active java processes running on a given machine. The output contains the JVMID, the name of the main class and any arguments passed to it or the JVM.

sharfah@starship:~> jps -lmv
3936 sun.tools.jps.Jps -lmv -Xms8m
5184 test.TestClient -Xmx1024m

2) jstat - statistics monitoring tool
This command allows you to monitor memory spaces of a JVM. For example, using the "-gcutil" option will show you the utilisation of the eden (E), survivor (S0, S1), old (O) and permanent (P) generations and how long the minor and major GCs are taking. You can gather these statistics continuously by specifying a sampling interval and how many samples you wish to take.

sharfah@starship:~> jstat -gcutil 5184 1s 5
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00   3.04  85.47  11.68      5    0.009     1    0.023    0.032
  0.00   0.00   3.04  85.47  11.68      5    0.009     1    0.023    0.032
  0.00   0.00   3.04  85.47  11.68      5    0.009     1    0.023    0.032
  0.00   0.00   3.04  85.47  11.68      5    0.009     1    0.023    0.032
  0.00   0.00   3.04  85.47  11.68      5    0.009     1    0.023    0.032

3) jstack - stack trace
Prints out a complete thread dump of your application (just like "kill -3"). Useful for investigating what your application is doing and identifying deadlocks.

4) jmap - memory map
Use this command to print a histogram of the heap to show you the number of instances of each java class and how much memory they are occupying. You can also dump the heap to a file in binary format and then load it into Eclipse Memory Analyser as I described here.

sharfah@starship:~> jmap -histo 5184
sharfah@starship:~> jmap -dump:format=b,file=heap.bin 5184

5) jhat - heap analysis tool
This command reads a binary heap file (produced by the jmap command, for example). It launches a local webserver so that you can browse the heap using a web browser. The cool thing is being able to execute your own queries using Object Query Language (OQL) on the heap dump.

sharfah@starship:~> jhat heap.bin

6) jinfo - configuration info
Prints out java system properties (like the classpath and library path) and JVM command line flags. Doesn't work on Windows though! Also allows you to enable/disable/change VM flags.

sharfah@starship:~> jinfo -flag PrintGCDetails  4648
-XX:-PrintGCDetails
sharfah@starship:~> jinfo -flag +PrintGCDetails 4648

Friday, April 18, 2008

Garbage Collection Performance Tips

The purpose of Java's Garbage Collector is to find and reclaim unreachable objects. This post will show you how you can write readable and clean code that makes the most out of the garbage collector (in terms of throughput, responsiveness etc)
  • Do not be afraid to allocate small objects for intermediate results. Typically, object allocation is very cheap and reclamation of new objects is very cheap too! GCs love small, immutable objects and generational GCs love small, short-lived objects. You should use short-lived immutable objects instead of long-lived mutable ones. Use clearer, simpler code with more allocations instead of more obscure code with fewer allocations.

  • Avoid large objects as they are expensive to allocate and initialise.

  • Nulling references rarely helps the GC. Instead it creates clutter and in the worst case may introduce a bug. The JIT can do liveness analysis very well.

  • Avoid explicit GCs. Applications do not have enough information, but GC does. Calling System.gc() at the wrong time, may start a full stop-the-world GC (in HotSpot) which can hurt performance with no benefit.

  • Avoid frequent resizing of array-based data structures as this will allocate several large-ish arrays and will cause a lot of array copying. Try to size them, on initialisation, as realistically as possible.

  • Only use object pools for objects that are expensive to allocate/initialise or for those that represent scarce resources e.g. database connection pools or thread pools. Use existing libraries wherever possible. Unused objects in pools are bad; they are live and so the GC must process them and they provide no benefit to the application.

  • Use finalization as a last resort. Finalizable object allocation is much slower and reclamation takes at least two GC cycles; the first cycle identifies object as garbage and enqueues object on finalization queue, the second cycle reclaims space after finalize() completes. Finalizers are not like C++ destructors! There is no guarantee if or when they will be called.

  • Memory leaks occur because objects are reachable but unused. This may be due to objects in the wrong scope, lapsed listeners, exceptions changing control flow, instances of inner classes, reference objects etc. You should perform reachability analysis to clear up these objects.