当前位置: 首页 > 知识库问答 >
问题:

为什么每个幸存者空间和伊甸园之间的比例不匹配SurvivorRatio?

李博达
2023-03-14

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

为什么幸存者和伊甸园的空间容量与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.

共有3个答案

濮阳鸿祯
2023-03-14

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

伊甸园的容量为1024.5 MB1024.5 / 6 = 107.75相当接近每个幸存者空间的107.5 MB。

翁昊乾
2023-03-14

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

尝试使用 Xms运行测试=

在我的例子中(使用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=

更新2:

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

更新3:

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

1号:未设置生存率,即应使用默认值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(生存空间)=size(伊甸园空间)/survivorRatio(示例:546.125/8=68.25-见测试2)
  • 隐式/默认幸存者比率:size(生存空间)=size(年轻一代)/surviorratio(示例:682/8=85.25——见测试1,数值四舍五入)

注意:对于jdk 1.8也是如此。

颛孙森
2023-03-14

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

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

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

 类似资料:
  • 你能回答我一个关于JVM垃圾收集过程的问题吗? 为什么堆被分为伊甸园、幸存者空间和老一代? 当一个年轻的疏散被处理时,通过从根开始的引用访问对象,以找出无法到达的对象。可到达的对象标记为“活动”,不可到达的对象不标记,将被删除。 因此,所有对象都会被考虑,包括旧一代中分配的对象也会被访问并标记是否可以访问。 据我所知,同时回收年轻一代和老一代是非常困难的,因为这两代人位于内存中不同的连续部分。 但

  • 在JVM重启之前,java(8)内存容量是否会减少? 我正在使用jstat-gc转储内存信息,下面是两天的快照。与第一个快照相比,第二个快照对SC1和EC的资本金更少。 有人能帮助/解释为什么我看到这种行为吗?这是预期的吗?

  • 我们的服务器应用程序似乎在一段时间内表现正常,但过了一段时间后,生存空间将填满100%,从那时起,堆使用量增加,GC周期(次要和主要)变得越来越频繁,最终堆耗尽。 这是“jstat-gcutil”的一部分 我的问题是这种应用程序行为背后的主要原因是什么?是太小的年轻空间或堆,其他一些JVM参数,还是只是一个普通的旧内存泄漏? 解决这个问题的最佳策略是什么,GC调优还是应用程序重构? JDK 1.6

  • 尝试查找这个,但是我遇到的所有问题/答案都谈到了拥有2个幸存者空间的目的。我想了解拥有幸存者空间的一般目的。将物体从伊甸园移动到幸存者有什么好处?

  • 这是来自太空的100%新的伊甸园--一个问题吗? 我的JAVA选项是:-xms10240m-xmx14336m-xx:permsize=192m-xx:maxpermsize=256m-xx:newsize=8192m-xx:maxnewsize=8192m-xx:-disableexplicitgc-xx:+useconcmarksweepgc-xx:cmsinitiatingoccupancy

  • 我需要帮助理解从和获得的与GC相关的数字如何与传递给Java的设置相关。我在内存为16GB的服务器上使用以下设置启动应用程序(solr): 的输出开始: 为什么、、和都这么小,而却很大?不应该吗?并且总的堆大小不应该接近吗?当设置为4时,为什么正好是的一半? 下面是输出的其余部分。它与上面的内容相匹配,并且包括一个部分,我也不知道如何解释。 此外,GC日志表明“期望的幸存者大小”是6.2MB,这也