【问题标题】:Why does the ratio between each survivor space and eden does not match SurvivorRatio?为什么每个幸存者空间和伊甸园之间的比率与 SurvivorRatio 不匹配?
【发布时间】:2016-04-21 08:45:44
【问题描述】:

SurvivorRatio 参数控制两个幸存者空间的大小。例如,-XX:SurvivorRatio=6 设置每个survivor空间和eden的比例为1:6,每个survivor空间将是年轻代的八分之一。

为什么survivor和eden的空间容量不匹配SurvivorRatio,如下图?由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.

【问题讨论】:

  • 这很奇怪,看起来你实际的 SurvivorRation 是 6,而不是 8。

标签: java jvm jmap


【解决方案1】:

似乎在某些时候计算伊甸园/幸存者空间大小的公式发生了变化。

参见https://searchcode.com/codesearch/view/17980811/,第 52 至 54 行:

幸存者比率是“原始”计算的,与默认 gc 不同,它将比率值加 2。在使用它们之前,我们需要确保这些值是有效的。

【讨论】:

【解决方案2】:

SurvivorRatio = 8 表示每个survivor空间占用大小为Eden + To + From的年轻代的1/8。在您的情况下,年轻代大小为 1365.5 MB,其中 1/8 为 170,69 - 假设涉及一些舍入(或其他一些小空间),这些值是合理的。

更新:我在这里有一些误解。您的情况下的值是有效的,空间可能还没有使用它们的最大容量。

尝试使用Xms=<value of Xmx> 运行测试。

就我而言(使用 jdk 1.6、1.7 和 1.8),我使用了 SurvivorRatio=10 并得到了以下结果(Java 8 有一些细微差别):

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

如您所见,两个幸存者空间正好是伊甸园空间大小的 10%。没有Xms=<Xmx>,我得到的百分比要低得多,因为空间还不必增加。

更新 2:

显然,OP 的空间已经获得了最大容量,年轻代的最大容量为 1365 MB(这是 4096 MB 最大堆大小的 33%)。在这种情况下,这些值看起来像幸存者比率为 6(即每个幸存者空间占用 eden 空间的 1/8),但 jmap 报告比率为 8 表示此处存在某种错误/错误(我使用 JVM 版本 21.0- b17 和 25.40-b25,即 OP 的版本 24.80-b11 介于两者之间)。

更新 3:

我使用 jdk 7 重新运行了两次测试:

No 1.:没有设置SurvivorRatio,即应该使用默认值 8:

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.:显式 SurvivorRatio=8 设置:

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)
   ...

正如您所见,尽管两种情况下报告的值都是 8,但该比率存在差异。只有比率明确设置为 8 的第二种情况符合文档中提供的等式,这表明在默认情况下使用了其他比率,并且 jmap 报告错误比率或实际大小计算使用不同的值/公式。

从值来看,公式如下所示:

  • 显式存活率:size(survior space) = size(eden space)/survivorRatio(例如:546.125 / 8 = 68.25 - 参见测试 2)
  • 隐式/默认幸存者比率:size(survior space) = size(young generation)/survivorRatio(例如:682 / 8 = 85.25- 参见测试 1,数值四舍五入)

注意:jdk 1.8 也是如此。

【讨论】:

  • @YanhuiZhou 问题是:你设置了SurvivorRatio=6 但jmap 报告SurvivorRatio=8 - 这表明你的设置没有被使用(8 是默认值)。请注意,您发布的文档已有 6 年历史,可能不再适用于当前的 JVM。
  • @YanhuiZhou 也看这里:stackoverflow.com/questions/3634465/… - 你可能没有禁用UseAdaptiveSizePolicy,所以设置幸存率不起作用。
  • 我没有设置SurvivorRatio=6,那只是来自url的参考内容。
  • @YanhuiZhou 我更新了答案,有一个误解。默认幸存者比率为 8,每个幸存者空间最多有 10% 的年轻代 (1 + 1 + 8)。如果您得到的值不匹配,这仅仅意味着空间还不需要最大容量。
  • @YanhuiZhou 我在我的机器上进行的测试中添加了另外 2 个更新。这些表明在您的案例中报告的 8 比率是错误的(将比率明确设置为 8 会产生正确的大小)。
【解决方案3】:

你的伊甸园与幸存者的比例是 6:1,因为有两个幸存者,幸存者与年轻空间的比例是 1/8

伊甸园的容量为 1024.5 MB 和 1024.5 / 6 = 107.75,非常接近每个幸存者空间的 107.5 MB。

【讨论】:

    猜你喜欢
    • 2018-05-10
    • 1970-01-01
    • 2012-08-11
    • 2013-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-23
    • 2012-08-03
    相关资源
    最近更新 更多