许多参数会影响分代大小。图4-1“堆参数”说明了堆中已提交空间和虚拟空间之间的差异。在虚拟机初始化时,将保留堆的整个空间。可以使用-Xmx选项指定保留空间的大小,如果-Xms参数的值小于-Xmx参数的值,并非所有保留的空间都立即提交给虚拟机。在此图中,未使用的空间标记为“虚拟”。堆的不同部分(使用永久代和年轻代)可以根据需要增长到虚拟空间的极限。
一些参数是堆的一部分与另一部分的比率。例如,参数NewRatio表示永久代与年轻代的相对大小。
Total Heap
以下有关增大和缩小堆以及默认堆大小的讨论不适用于并行收集器。有关调整并行收集器的堆大小和默认堆大小的详细信息,请参阅“调整世代大小”中的“并行收集器人机工程学”一节。)但是,控制堆总大小和分代大小的参数确实适用于并行收集器。
影响垃圾收集性能的最重要因素是总可用内存。由于收集是在永久代填满时发生的,因此吞吐量与可用内存量成反比。
默认情况下,虚拟机会在每个集合上增加或缩小堆,以尝试将每个集合中活动对象的可用空间比例保持在特定范围内。该目标范围由参数-XX:MinHeapFreeRatio = <minimum>和-XX:MaxHeapFreeRatio = <maximum>设置为百分比,总大小的下限为-Xms <min>,上限为-Xmx <max> 。表4-1“ 64位Solaris操作系统的默认参数”中显示了64位Solaris操作系统(SPARC平台版本)的默认参数:
表4-1 64位Solaris操作系统的默认参数:
使用这些参数,如果某代中的可用空间百分比降到40%以下,那么该代将被扩展以维持40%的可用空间,,直至最大允许生成的大小。同样,如果可用空间超过70%,则将收缩该世代,以便只有70%的空间是空闲的,这取决于该世代的最小大小。
如表4-1“ 64位Solaris操作系统的默认参数”中所述,默认的最大堆大小是由JVM计算的值。Java SE中用于并行收集器和服务器JVM的计算现在用于所有垃圾收集器。计算的一部分是最大堆大小的上限,这对于32位平台和64位平台而言是不同的。请参阅“并行收集器”中的“默认堆大小”部分。客户端JVM的计算与此类似,这导致最大堆大小小于服务器JVM。
以下是有关服务器应用程序堆大小的一般准则:
- 除非您在暂停方面遇到问题,否则请尝试为虚拟机分配尽可能多的内存。默认大小通常太小。
- 将-Xms和-Xmx设置为相同的值可以通过从虚拟机中删除最重要的大小确定决策来提高可预测性。但是,如果选择不当,虚拟机将无法补偿
- 通常,由于分配可以并行化,因此随着处理器数量的增加而增加内存。
The Young Generation
在总可用内存之后,影响垃圾收集性能的第二大影响因素是专用于年轻一代的堆的比例。年轻一代越大,垃圾的次数就越少。但是,对于有限的堆大小,较大的年轻代意味着较小的终身代,这将增加主要集合的频率。最佳选择取决于应用程序分配的对象的生命周期分布。
默认情况下,年轻代大小由参数NewRatio控制。例如,设置-XX:NewRatio = 3表示年轻一代和老年一代之间的比率为1:3。换句话说,eden区和survivor区的总大小将是堆总大小的四分之一。
参数NewSize和MaxNewSize从下方和上方限制了年轻代的大小。将这些值设置为相同的值可以修复年轻一代,就像将-Xms和-Xmx设置为相同的值可以修复总堆大小一样。这对于以比NewRatio允许的整数倍更好的粒度调整年轻代很有用。
Survivor Space Sizing
您可以使用参数SurvivorRatio来调整幸存空间的大小,但这对性能通常并不重要。例如,-XX:SurvivorRatio = 6将eden区和survivor区之间的比率设置为6:1。换句话说,每个幸存者空间将是伊甸园大小的六分之一,因此是年轻一代的八分之一(而不是七分之一,因为有两个幸存者空间)。
如果幸存者空间太小,则复制集合将直接溢出到终身代。如果幸存者空间太大,它们将毫无用处。在每次垃圾回收时,虚拟机都会选择一个阈值数字,该阈值是对象在使用期限之前可以复制的次数。选择此阈值可使幸存者填满。命令行选项-XX:+ PrintTenuringDistribution(并非在所有垃圾收集器上都可用)可用于显示此阈值和年青代对象的寿命。这对于观察应用程序的生命周期分布也很有用。
表4-2“幸存者空间大小调整的默认参数值”提供了64位Solaris的默认值:
根据总堆的最大大小和NewRatio参数的值来计算年轻代的最大大小。MaxNewSize参数的“不受限制”默认值表示,除非在命令行上指定了MaxNewSize的值,否则计算值不受MaxNewSize的限制。
以下是服务器应用程序的一般准则:
-
首先确定您可以负担得起的虚拟机的最大堆大小。然后针对年轻一代绘制性能指标,以找到最佳设置。
- 请注意,最大堆大小应始终小于计算机上安装的内存量,以避免过多的页面错误和崩溃。
-
如果总堆大小是固定的,则增加年轻代的大小需要老年代数的大小。
-
使老年代足够大,以容纳应用程序在任何给定时间使用的所有实时数据,以及一定数量的闲置空间(10%到20%或更多)。
-
遵循先前对老年代的约束:
- 给年轻一代留下很多记忆。
-
随着处理器数量的增加,可以增加年轻代的大小,因为分配可以并行化。
原文
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/sizing.html
网友评论