5

Most of the place on net , I get below info about heap parameters

-Xms<size> set initial Java heap size -Xmx<size> set maximum Java heap size

Here is mine understanding/question when I mention -Xms 512M -Xmx 2048M parameters ,

-Xms :- My understanding is if my java process is actually needed only 200M , with mention of -Xms 512M , java process will still be assigned only 200M(actual memory required) instead of 500M . But if I already know that my application is going to take this 512M memory on start up then specifying less than will have impact on performance as anyways heap block need to resized which is costly operation.

Per discussion with my colleague, By default GC will trigger on 60% of Xms value. Is that correct ? If yes is it minor GC or full GC that is dependant on Xms value ?

Update on Xms:- This seems to be true after reading JVM heap parameters but again is value 60% by default and is it minor or full GC that is dependent on Xms value?

-Xmx:- My understanding is with mention of -Xmx 2048M , java process is actually going to reserve 2048M memory for its use from OS itso that another process can not be given its share.If java process needed anyhow more than 2048M memory, then out of memory will be thrown.

Also i believe there is some relation of Full GC trigger on value of -Xmx. Because what I observed is when memory reaches near to 70% of Xmx, Full GC happens in jconsole. Is that correct?

Configuration :- I am using linux box(64 bit JVM 8). Default GC i.e Parallel GC

trincot
  • 317,000
  • 35
  • 244
  • 286
emilly
  • 10,060
  • 33
  • 97
  • 172

1 Answers1

7

GC is not triggered based on just Xms or Xmx value.

Heap = New + Old generations
The heap size (which is initially set to Xms) is split into 2 generations - New (aka Young) and Old (aka Tenured). New generation is by default 1/3rd of the total heap size while Old generation is 2/3rd of the heap size. This can be adjusted by using JVM parameter called NewRatio. Its default value is 2.

Young Generation is further divided in Eden and 2 Survivor spaces. The default ratio of these 3 spaces are: 3/4th, 1/8th, 1/8th.

Side note: This is about Parallel GC collectors. For G1 - new GC algorithm divides the heap space differently.

Minor GC All new objects are allocated in Eden space (except massive ones which are directly stored in Old generation). When Eden space becomes full Minor GC is triggered. Objects which survive multiple minor GCs are promoted to Old Generation (default is 15 cycles which can be changed using JVM parameter: MaxTenuringThreshold).

Major GC Unlike concurrent collector, where Major GC is triggered based on used-space (by default 70%), parallel collectors calculate threshold based on 3 goals mentioned below.

Parallel Collector Goals

  • Max GC pause time - Maximum time spent in doing GC
  • Throughput - Percentage of time spent in GC vs Application. Default (1%)
  • Footprint - Maximum heap size (Xmx)

Thus by default, Parallel Collector tries to spend maximum 1% of total application running time in Garbage Collection.

More details here

Xms to Xmx
During startup JVM creates heap of size Xms but reserves the extra space (Xmx) to be able to grow later. That reserved space is called Virtual Space. Do note that it just reserves the space and does not commit.

2 parameters decide when heap size grows (or shrinks) between Xms and Xmx.

  • MinHeapFreeRatio (default: 40%): Once the free heap space dips below 40%, a Full GC is triggered, and the heap size grows by 20%. Thus, heap size can keep growing incrementally until it reaches Xmx.
  • MaxHeapFreeRatio (default: 70%): On the flip side, heap free space crosses 70%, then Heap size is reduced by 5% incrementally during each GC until it reaches Xms.

These parameters can be set during startup. Read more about it here and here.

PS: JVM GC is fascinating topic and I would recommend reading this excellent article to understand in-depth. All the JVM tuning parameters can be found here.

DeepakV
  • 2,420
  • 1
  • 16
  • 20
  • Deepak. Great explanation. but one quick question you said `Once the free heap space dips below 40%, a Full GC is triggered,` it mean full GC will be triggered as soon as 60 or 61% heap is consumed. But I found another contradictory statement in your answer i.e. `... Major GC is triggered based on used-space (by default 70%)..` . so will full GC be triggered if heap usage crosses 60% or 70% by default ? – emilly Sep 24 '16 at 11:20
  • Full GC is triggered for 2 separate reasons. For parallel collector, first is when based on goal of spending 1 percent of time doing GC (it creates its own heuristics internally for this). Second reason is to ensure that free space is never more than 70% (this triggers GC, then space is compacted and then old generation is shrunk) and never less than 40% (this triggers GC, then compaction, then old generation is expanded). In fact that's precisely the reason it's recommended to have xms and xmx as the same value, to avoid these time consuming full GC – DeepakV Sep 24 '16 at 11:29
  • say I have 1G of old generation. It means if old generation continues to use less than 300M then full GC will trigger and shrink it(shrink both yound and old gen). Similarly if old gen uses more than 600M of heap then also GC will trigger and expand it((expand both young and old gen)). Is that correct ? – emilly Sep 24 '16 at 14:24
  • Close. My bad, I should have been clearer. Adjusting sizes based on percentage of free space, applies to both Young and Old generation. See this image. http://4.bp.blogspot.com/-7aT-vEsf1ck/UeV-q1u2qUI/AAAAAAAAAIs/9PK5-OpEL5I/s1600/Generations.png So, like I gave example of old generation space, even in young generation, if free space goes more than 70% of young generation or less 40% of young generation, the young-generation is resized. Thus, the triggering will be based on free-space percentages of each generation and not exactly < 400MB or > 700MB – DeepakV Sep 24 '16 at 14:33
  • @DeepakV, are the parameters `MinHeapRatio` and `MaxHeapRatio` applicable to Parallel GC? The link https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/sizing.html#sizing_generations mentions that "The following discussion regarding growing and shrinking of the heap and default heap sizes does not apply to the parallel collector." – Chetan Yewale Sep 27 '20 at 14:54