1

The SurvivorRatio parameter controls the size of the two survivor spaces. For example, -XX:SurvivorRatio=6 sets the ratio between each survivor space and eden to be 1:6, each survivor space will be one eighth of the young generation.

Why does the space capacity of survivor and eden not match SurvivorRatio, as below? Produced by jmap -heap 15760.

Attaching to process ID 15760, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 24.80-b11

using thread-local object allocation.
Parallel GC with 8 thread(s)

Heap Configuration:
   MinHeapFreeRatio = 0
   MaxHeapFreeRatio = 100
   MaxHeapSize      = 4294967296 (4096.0MB)
   NewSize          = 1310720 (1.25MB)
   MaxNewSize       = 17592186044415 MB
   OldSize          = 5439488 (5.1875MB)
   NewRatio         = 2
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 1073741824 (1024.0MB)
   G1HeapRegionSize = 0 (0.0MB)

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 1074266112 (1024.5MB)
   used     = 276841328 (264.01646423339844MB)
   free     = 797424784 (760.4835357666016MB)
   25.770274693352704% used
From Space:
   capacity = 178782208 (170.5MB)
   used     = 56996280 (54.35588836669922MB)
   free     = 121785928 (116.14411163330078MB)
   31.880286432081654% used
To Space:
   capacity = 178782208 (170.5MB)
   used     = 0 (0.0MB)
   free     = 178782208 (170.5MB)
   0.0% used
PS Old Generation
   capacity = 2863661056 (2731.0MB)
   used     = 98320 (0.0937652587890625MB)
   free     = 2863562736 (2730.906234741211MB)
   0.003433367220397748% used
PS Perm Generation
   capacity = 47710208 (45.5MB)
   used     = 47664440 (45.45635223388672MB)
   free     = 45768 (0.04364776611328125MB)
   99.90407084370707% used

26132 interned Strings occupying 2933384 bytes.
AlBlue
  • 23,254
  • 14
  • 71
  • 91
Yanhui Zhou
  • 872
  • 6
  • 20

3 Answers3

2

SurvivorRatio = 8 means that each survivor space takes 1/8th of the young generation whose size is Eden + To + From. In your case The young generation size is 1365.5 MB and 1/8th of that would be 170,69 - assuming there's some rounding involved (or some other small space) the values are sound.

Update: I had some misconception here. The values in your case would be valid, the spaces probably just haven't used their maximum capacity yet.

Try running a test with Xms=<value of Xmx>.

In my case (with a jdk 1.6, 1.7 and 1.8) I used SurvivorRatio=10 and got the following results (Java 8 had some slight differences):

Heap Configuration:
  ...   
  SurvivorRatio    = 10
  ...

Heap Usage:
PS Young Generation
Eden Space:
  capacity = 596508672 (568.875MB)  //Java 8 reported 569.5 here
  used     = 536159440 (511.3214874267578MB)
  free     = 60349232 (57.55351257324219MB)
  89.8829246190741% used
From Space:
  capacity = 59637760 (56.875MB)    //Java 8 reported 56.5 here
  used     = 59626360 (56.86412811279297MB)
  free     = 11400 (0.01087188720703125MB)
  99.9808845939217% used
To Space:
  capacity = 59637760 (56.875MB)    //Java 8 reported 56.5 here
  used     = 0 (0.0MB)
  free     = 59637760 (56.875MB)
  0.0% used

As you can see, both survivor spaces are exactly 10% the size of the eden space. Without Xms=<Xmx> I got way lower percentages as the spaces didn't have to be increased yet.

Update 2:

Apparantly the OP's spaces already aquired their maximum capacity with young generation having 1365 MB max (which is 33% of the 4096 MB max heap size). In that case the values look like the survivor ratio being 6 (i.e. each survivor space taking 1/8th of eden space) but jmap reporting a ratio of 8 indicates some kind of error/bug here (I did my tests with JVM version 21.0-b17 and 25.40-b25, i.e. the OP's version 24.80-b11 is somewhere in between).

Update 3:

I reran my tests twice with jdk 7:

No 1.: no SurvivorRatio set, i.e. default of 8 should be used:

Heap Configuration:
   ...
   SurvivorRatio    = 8
   ...

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 536870912 (512.0MB)
   ...
From Space:
   capacity = 89456640 (85.3125MB)
   ...
To Space:
   capacity = 89456640 (85.3125MB)
   ...

No 2.: explicit SurvivorRatio=8 set:

Heap Configuration:
   ...
   SurvivorRatio    = 8
   ...

Heap Usage:
PS Young Generation
Eden Space:
   capacity = 572653568 (546.125MB)
   ...
From Space:
   capacity = 71565312 (68.25MB)
   ...
To Space:
   capacity = 71565312 (68.25MB)
   ...

As you can see there's a difference in the ratio even though a value of 8 is reported for both cases. Only the second case where the ratio was explicitly set to 8 fits the equation provided in the documentation which indicates in the default case there's some other ratio being used and jmap either reports a wrong ratio or the actual size calculation use a different value/formula.

From the values the formulas look like this:

  • explicit survivor ratio: size(survior space) = size(eden space)/survivorRatio (example: 546.125 / 8 = 68.25 - see test 2)
  • implicit/default survivor ratio: size(survior space) = size(young generation)/survivorRatio (example: 682 / 8 = 85.25- see test 1, values rounded a bit)

Note: this also is true for jdk 1.8.

Thomas
  • 87,414
  • 12
  • 119
  • 157
  • @YanhuiZhou the problem is: you set `SurvivorRatio=6` but jmap reports `SurvivorRatio=8` - that indicates your settings are not used (8 is the default). Note that the documentation you posted is 6 years old and probably doesn't apply to current JVMs anymore . – Thomas Apr 21 '16 at 09:27
  • 1
    @YanhuiZhou also look here: http://stackoverflow.com/questions/3634465/useadaptivesizepolicy-and-other-jvm-opts - Chances are you didn't disable `UseAdaptiveSizePolicy` so setting the survior ratio won't work. – Thomas Apr 21 '16 at 09:33
  • I am not set SurvivorRatio=6, that is just the reference content from the url. – Yanhui Zhou Apr 21 '16 at 09:35
  • @YanhuiZhou I updated the answer, there was a misconception. With the default survivor ratio of 8 each survivor space has a maximum of 10% of the young generation (1 + 1 + 8). If the values you get don't match that simply means the spaces didn't require their maximum capacity yet. – Thomas Apr 21 '16 at 09:50
  • @YanhuiZhou I added another 2 updates on tests I did on my machine. Those indicate the ratio of 8 being reported in your case is wrong (setting the ratio to 8 explicitly yields the correct sizes). – Thomas Apr 21 '16 at 10:13
2

It seems that at some time the formula for calculating the eden / survivor space size has changed.

See to https://searchcode.com/codesearch/view/17980811/, lines 52 to 54:

The survivor ratio's are calculated "raw", unlike the default gc, which adds 2 to the ratio value. We need to make sure the values are valid before using them.

Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • That's exactly what I suspected and was looking for. As in "read the code, the documentation lies" ;) – Thomas Apr 21 '16 at 09:34
  • @ThomasKläger I accidentally stumbled against this, but i don't think this is correct. The `plus 2` is referenced here : http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/tip/src/share/vm/runtime/arguments.cpp#l1573. That's not a `SurvivorRatio - 2` at all... – Eugene May 05 '17 at 13:20
1

Your eden to survivor ratio is 6:1, as the there is two survivors, the ratio of the survivors to young space is 1/8th

The Eden has a capacity of 1024.5 MB and 1024.5 / 6 = 107.75 which is pretty close to the 107.5 MB for each survivor spaces.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130