Understanding GC for Memory Problems: Part-2
In earlier part we have seen how memory is allocated to JVM on start up and brief about what GC is, let’s look at what are the parameters are available to tune the Heap size and Garbage collector, to work efficiently.
Normally parameters selected default by JVM helps application to run smooth it is called Ergonomics where it dynamically adjust heap space, but when you require high performance with applications that has high load of concurrent users or large volume of data, The best performance can be achieved in two steps
- by tweaking the parameters for the heap size first and then
- To use appropriate GC collectors for better throughput.
We will see both. There are many parameters available for JVM but I will present only few relevant here.
To Change Heap Size
| -Xmn<n> | Size of young generation. This will not have any effect if NewSize is mentioned. |
| -xms<n> | Initial size of total heap |
| -xmx<n> | Maximum size of total heap |
| –XX:NewSize=<n> | Initial size of young generation. |
| –XX:MaxNewSize=<n> | Maximum new size of young generation |
| -XX:PermSize=<n> | Initial Param Size, it is a non heap memory |
| -XX:MaxPermSize=<n> | Maximum Param Size |
| -XX:NewRatio=<n> | Ratio of new/old generation size. If NewSize is mentioned then this will be ignored or have no effect. Here it will be calculated as NewSize =(xms/<n>) For e.g. for 120mb heap NewSize will be 40mb if n is 3 |
| - XX:SurvivorRatio=<n> | Ratio of Eden:survivor space. If ignored calculated internally and adjusted dynamically. Default is 8 so if I allocate NewSize = 200mb then survivor will be allocated 25mb each. |
If we pass following parameters to JVM at startup see how memory is allocated
export JAVA_OPTS='-server -Xms1175m -Xmx1175m -XX:NewSize=550m -XX:MaxNewSize=550m -XX:PermSize=125m -XX:MaxPermSize=125m'
note: m stands for size in megabytes
Note that if newratio is not mentioned, then Old/tenured size is calculated as (total heap) – (NewSize). Also note that survivorratio is taken as 8 here calculated dynamically
For sizing Heap try to first find out existing allocation use JMAP/JVISUALVM or other tools for existing sizing. (I have mentioned below note about it)
GC Tunning Parameters
Note + sign invokes multi threaded and – invokes single threaded GC
| Used for Parallel Collector | -XX:+UseParNewGC | This flag turns on parallel garbage collection in the young generation. It can be enabled together with the CMS collector in the old generation. |
| Used for Parallel Collector | -XX:ParallelGCThreads=n | Sets the number of parallel GC threads that the JVM must run for performing garbage collection in the young generation. The default value of n is equal to the number of CPUs on the system. |
| Used for Parallel Collector | -XX:+UseParallelGC | This flag also turns on parallel garbage collection policy in the young generation; however, it does not work with the CMS collector in the old generation |
| Used for Parallel Collector/Throughput Collectors | -XX:+UseParallelOldGC | enable parallel compaction for old GC |
| Concurrent Collector/ low pause collector | -XX:+UseConcMarkSweepGC | This turns on concurrent garbage collection in the old generation |
| Concurrent Collector | -XX:CMSInitiatingOccupancyFraction= x | Sets the threshold percentage of the used heap in the old generation at which the CMS collection takes place. For example, if set to 60, the CMS collector will be initiated every time the old generation becomes 60% full |
| other | -XX:MaxTenuringThreshold=x | This switch determines how much the objects may age in the young generation before getting promoted to the older generation. The default value is 31. For a big enough young generation and “survivor space”, the long-lived objects may be copied up to 31 times between the survivor spaces before they are finally promoted to the old generation.This option will be good combination if used with CMS collector. |
| other | -XX:TargetSurvivorRatio=x | This flag sets the desired percentage of the survivor space heap which must be used before objects are promoted to the old generation. For example, setting z to 90 would mean that 90% of the survivor space must be used before the young generation is considered full and objects are promoted to the old generation. This would allow objects to age more in the young generation before being tenured. The default value is 50. Available from J2SE1.3 |
Points for tuning
- Try first Ergonomics — Automatic Selections and Behavior Tuning
- If you cannot measure the application measure the machine. Means use large size of heap available on the machine that your hardware supports.
- There is no problem having large heap if you know the GC pauses and are acceptable for application.
- Swapping memory means starvation, it’s a hell.
- GC performance is proportion to heap size dedicated to young.
- Using serial collector (1cpu) make sure you do not allocate more than half of heap size. When using parallel collector it is better to specify desired behavior rather than exact heap size values. Let the collector automatically and dynamically modify the heap sizes in order to achieve that behavior
- Most cases it is preferred to allocate 40-60 /30-70 ratio to young and old size.
- Do not allocate more memory to parmgen, its waste… Try to find out how much it uses by accessing application first and then add 20% extra to it. Generally it will be 10-15% for your total heap size. Use jstat or jmap to find usage.
Tools to monitor GC performance and heap sizing
JSTAT : this tool is a command line tool available with JDK5 it provides the GC statistic, helps to understand GC behavior. It can be invoked as below.
jstat –gcutil <processeid> <n seconds to repeat> <n no of repeats>
e.g. root$:> /home/jdk/bin/jstat –gcutil 6584 3s 5
Above command will give output as below after every 3 seconds five times
| S0 | S1 | E | O | P | YGC | YGCT | FGC | FGCT | GCT |
| 0.00 | 12.46 | 10.96 | 81.40 | 39.37 | 68539 | 1867.261 | 183 | 206.407 | 2073.667 |
Following is the column headings
S0/s1 – survivor space, E – Eden, O- Old, P- Permgen, YGC – Young GC, YGCT – YGC Time, FGC – Full GC, FGCT – FGC Time, GCT – Cumulative GC Time.
JMAP : this tool is a command line tool available with JDK5 it provides heap information allocated to JVM, it also helps to find live objects in the memory by taking heap dump. Command syntax is as follows
jmap –<heap/histo> <processeid>
e.g.
root$:> /home/jdk/bin/jmap –heap 6584
root$:> /home/jdk/bin/jmap –histo 6584
root$:> /home/jdk/bin/jmap –histo:live 6584
First example gives summery info of heap size allocation and also used and free space info.
Second and third example gives dump of objects, its instance count and bytes allocated figures, if use “:live” option gives only live objects.
JVISUALVM: this tool is a visual representation of GC and heap size.
Read more articles:
More about GC and how it works in detail
http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html#par_gc.oom
http://developers.sun.com/mobility/midp/articles/garbage/index.html
Different tuning ideas and sizing examples mentioned
http://java.sun.com/performance/reference/whitepapers/tuning.html
http://blogs.sun.com/partnertech/entry/a_short_primer_to_java
all jvm parameter options
http://blogs.sun.com/watt/resource/jvm-options-list.html
http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#PerformanceTuning
FAQ about GC
http://java.sun.com/docs/hotspot/gc1.4.2/faq.html
Mislenious
http://blogs.sun.com/fkieviet/entry/classloader_leaks_the_dreaded_java


Nice & important information which is rarely found.I like it very much.
Thanks for the information.
Sandeep Natoo
January 7, 2010 at 3:21 pm