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.
字符串
4条答案
按热度按时间oyxsuwqo1#
SurvivorRatio = 8
意味着每个幸存者空间占用年轻一代的1/8,其大小为Eden + To + From。在您的情况下,年轻一代的大小为1365.5 MB,其1/8将是170,69-假设有一些舍入(或其他小空间),这些值是合理的。**更新:**我在这里有一些误解。在你的情况下,值是有效的,空间可能还没有使用它们的最大容量。
尝试使用
Xms=<value of Xmx>
运行测试。在我的例子中(使用jdk 1.6、1.7和1.8),我使用
SurvivorRatio=10
并得到以下结果(Java 8有一些细微的差异):字符串
正如你所看到的,两个幸存者空间的大小都是伊甸园空间的10%。没有
Xms=<Xmx>
,我得到的百分比要低得多,因为空间还没有增加。更新二:
显然OP的空间已经获得了最大容量,年轻一代最大容量为1365 MB(这是4096 MB最大堆大小的33%)。(即每个幸存者空间占用伊甸园空间的1/8)但jmap报告的比率为8表示此处存在某种错误/bug(我用JVM版本21.0-b17和25.40-b25进行了测试,即OP的版本24.80-b11介于两者之间)。
更新三:
我用jdk 7重新运行了两次测试:
No 1.:未设置
SurvivorRatio
,即应使用默认值8:型
No 2.:explicit
SurvivorRatio=8
set:型
正如你所看到的,尽管两种情况下都报告了值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也是如此。
roqulrg32#
你的伊甸园与幸存者的比例是6:1,因为有两个幸存者,幸存者与年轻空间的比例是1/8。
Eden的容量为1024.5 MB,1024.5 / 6 = 107.75,非常接近每个幸存者空间的107.5 MB。
x759pob23#
为了扩展并澄清Thomas's answer中所述的行为,两种情况下的差异是由于显式指定
SurvivorRatio
标志和不指定相同标志的情况的处理方式。剧透警告- jmap输出(即SurvivorRatio = 8)也不是完全错误的。你会问为什么?沿着:有3个与生存率相关的选项-
SurvivorRatio
,MinSurvivorRatio
和InitialSurvivorRatio
。这些选项的默认值(可以在源代码gc_globals.hpp中找到)分别为8,3和8。从源代码中可以清楚地看到:SurvivorRatio
考虑比率Eden:SurvivorMinSurvivorRatio
和InitialSurvivorRatio
考虑了年轻一代:幸存者的比例根据this Oracle错误单,
垃圾邮件收集器使用命令行标志
MinSurvivorRatio
和InitialSurvivorRatio
。(Note实际上
Parallel scavenge
是GC的名称,而Parallel scavenge
是明确告诉JVM使用此GC的标志。根据this Oracle错误单,
SurivorRatio
k
的值将产生InitialSurvivorRatio=(k+2)
和MinSurvivorRatio=(k+2)
,如果是Parallel Scavenger
(源代码:parallelArguments.cpp)(并行清除器是默认的GC。从代码中可以看出,只有在指定了SurivorRatio但未指定这两个标志时,才会以这种方式为这两个标志赋值。)
如果没有指定
SurvivorRatio
和其他两个标志,则将使用gc_globals.hpp
中指定的默认值。并行Scavenger只关心MinSurvivorRatio
和InitialSurvivorRatio
的默认值。因此,我们认为,
在这两种情况下,SurvivorRatio的值都是8,因此jmap将输出8。
这个答案假设
XX:UseAdaptiveSizePolicy
标志被禁用(显式地,因为它在默认情况下是启用的),因为根据IBM docs:避免麻烦:-XX:SurvivorRatio=选项与JVM参数-XX:+AdaptiveSizePolicy不兼容。请根据您的情况使用其中一个。
xj3cbfub4#
似乎在某个时候,伊甸园/幸存者空间大小的计算公式已经改变了。
参见https://searchcode.com/codesearch/view/17980811/,第52至54行:
幸存者比率是“原始”计算的,不像默认的gc,它在比率值上加2。我们需要在使用它们之前确保这些值是有效的。