Tuesday, April 12, 2011

Simple Guide To Understand Resource Profile of Java Application

Synopsis

This note describes a few simple commands on how to view the RAM and CPU usage of your Java process. It provides brief pointers on how to identify the influencing parameters and how to tweak it.

Memory

Java Heap

The heap size of your Java process can be controlled by using a combination of –Xmx and –Xms.
The heap size being used at any point of time, and the behavior of the garbage collections can be understood by analyzing the output of the –verbose:gc argument to the JVM.
Please see:
http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html (Section 3.2)

Native Memory

This is the RAM that the java process consumes on the native system.
On Solaris, a simple command will provide this information.

ps -eo "user pid rss time comm"  | grep java
(RSS – The “resident set size” of the process, in kilobytes)
e.g. – In our scenario, we realized that while the maximum heap in java had been set to 64M (-Xmx), the RAM utilized on Solaris was ~120M.
There are instances where the RAM consumed by the Java process is upto 6 times the specified Java heap size for different flavours of Unix.
Please see:
man ps
http://en.wikipedia.org/wiki/Resident_set_size

CPU

In a long running java process, you’d be interested in the cumulative CPU time consumed.

ps -eo "user pid rss time comm"  | grep java
Here “time” will show you the cumulative CPU time consumed since the process started.
This can be run at regular intervals or as required , to understand the CPU usage when the java process is used/invoked.
(This will be especially important in scenarios when you are migrating to Java, when Java comes across as CPU hungry when compared to C/ C++).

Java tools

There are several tools bundled with Java. Some that can be easily used to assist you are:

JStack

jstack prints Java stack traces of Java threads for a given Java process.
You can use this to get an idea of what’s going in you java process, which java classes are being loaded and so on.
Please see:
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstack.html
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html

Jmap

Jmap shows you the native libraries used in your Java process.
Please see:
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html

Others

Please see the list of Java tools at http://java.sun.com/j2se/1.5.0/docs/tooldocs/
(Please see the section on “Monitoring and Management Tools” and “Troubleshooting Tools” )

JVM options

There are several JVM options available. For a complete listing:
Please see:
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp
The only options discussed here are “–server “ & “-client”.
In our scenario, we saw an improvement of roughly 33% in the usage of RAM and CPU when we used “-client” over “–server” option.
However, which option to use will depend upon your specific scenario. Points to consider include the size of the component, libraries in use, usage characteristics (e.g. – long running as in a daemon, or one time use as a client). It could also come about by trial and error as you use or simulate the component’s working environment.
Roughly the theory about using either of the two is:
The –client option is optimized to start the java process quickly. It executes the application as bytecode.
The –server option is optimized to best use the resources available on a server grade machine. With respect to the application, it notes the usage and eventually compiles the bytecode to native executable. Thus surpassing the –client performance benchmark in the long run.
So for quick startup and fewer resources use the –client option. If more resources are available and better performance required in long run, use the –server option.
That’s the theory, but you’ll have to verify the behavior yourself for your application.
Please see the discussion on
http://www.velocityreviews.com/forums/t130082-difference-between-client-server-classic-and-hotspot-jvms.html

Factors Influencing the Resource Usage

Some examples are provided for factors affecting these parameters.
  • As we’ve seen above, the CPU and RAM utilised differs considerably depending on the JVM parameters used.
  • The libraries used. e.g. – we noticed a fair difference between use of a type 2 and type 4 driver to connect to the database. (The type 2 driver was more expensive both in terms of CPU and RAM)
  • Naturally, operations that are performed by the application. In our case, we noted that IO to the file system took up a huge amount of CPU. (In this case writing to the log file. If you are able to redirect the standard output to the log file instead, the CPU for this activity doesn’t get attributed to your component :) )
  • Very interestingly, even an idle java process will consume CPU. Please see an interesting note on this. http://blogs.sun.com/nickstephen/entry/java_why_does_my_jvm

Summary

After you’re through tweaking and tuning your Java application within the JVM, you still need to concern yourself with how it performs on the native (Unix ) environment. This note attempts to give some pointers on where to begin from and what to look out for. Hope it will be helpful.

No comments:

Post a Comment

Chitika