I have read this article about virtual machine garbage collection tuning to understand the java garbage collector better. Each space has a Virtual heap space area which it can grow into as the heap space needed gets closer to the max heap size. This can be seen in this picture: Java GC arrangement of generations http://www.oracle.com/ocom/groups/public/@otn/documents/digitalasset/190244.gif
You can set the ratio between Young Generation and Old (Tenured) Generation with the NewRatio parameter, and the ratio between Eden Space and Survivor Space with the SurvivorRatio parameter.
Recently this question was asked about finding out the default ratios for the heap spaces. It says you should use the PrintGCDetails parameter and calculate the ratios manually.
My question is: Does the size of the different heap spaces increase by the same ratio, thus keeping the ratio set between them at startup constant during the whole runtime of the application? For example, if Young Generation and Old/Tenured Generation has a default NewRatio of 3, and the initial reserved heap space is 100MB for Young, and 300MB for Old. If more memory needs to be reserved for the Old Space, lets say 300MB more making it 600MB total. Does memory reserved for Young Space also double to 200MB keeping the ratio intact?
PermGen vs Young generation ratio is partially maintained by JVM, but to say if ratio is maintained, the answer is No.
JVM7 has become sufficiently advanced and complicated where we shouldn't predict the allocation of generations inside heap.
In every GC cycle that JVM runs, it also does metric analysis to learn of current applications in-memory storage behavior. - If more objects are surviving the multiple cycles of GC, then PermGen is reduced and some of the space is allocated to YoungGeneration. Basically
No. of objects
xnumber of GC cycles they skip
plays a criteria in dynamically adjusting the generation ratio.I hope it helps, thanks.
Edit: I think I may have something wrong. Putting this note here while I investigate, to keep from sending folks down the wrong path!
Ales0x's answer is great if you are using Parallel Scavenge GC (
-XX:+UseParallelGC
), but Concurrent Mark-Sweep GC (-XX:+UseConcMarkSweepGC
) does not support adaptive sizing.With Concurrent Mark-Sweep, the new/young generation size is set based on the initial heap size (unless you specify
-XX:NewSize=
). The new generation size will not change as the heap grows.I think you are referring to GC Ergonomics and the Adaptive Size Policy
-XX:SurvivorRatio=
.You can disable the Adaptive Size Policy by using the
-XX:-UseAdaptiveSizePolicy
. Once you disabled the AdaptiveSizePolicy, the GC will respect the initial size of the generations as specified by your startup parameters (e.g.-Xms
,-Xmx
,-XX:MaxNewSize=
,-XX:NewSize=
,-XX:SurvivorRatio=
) and they will remain constant.You can find more on Adaptive Size policy in UseAdaptiveSizePolicy and other jvm opts.