【HotSpot虚拟机垃圾回收调优指南】4.影响垃圾收集性能的因素

 影响垃圾收集性能的两个最重要的因素是总可用内存和专用于年轻代的堆大小的比例

 

目录

一.总堆(Total Heap)

1.1.堆参数(Heap Options)影响分代(Generation)大小

1.2.堆大小的默认值 

1.3.通过最小化Java堆大小来节省动态占用空间

二.年轻代(Young Generation)

2.1.年轻代(Young Generation)大小参数

2.2.幸存空间(survivor spaces)大小


一.总堆(Total Heap)

影响垃圾收集性能的最重要因素是总可用内存。因为集合发生在"代"满时,所以吞吐量与可用内存成反比。

注意:
    以下有关堆的增长和收缩,堆布局和默认值的讨论使用串行收集器作为示例。 
虽然其他收集器使用类似的机制,但此处提供的详细信息可能不适用于其他收集器。
有关其他收集器的类似信息,请参阅相应主题。

1.1.堆参数(Heap Options)影响分代(Generation)大小

许多参数会影响分代的大小。下图中“堆参数”说明了堆中的已提交空间和虚拟空间之间的差异。在初始化虚拟机时,将保留堆的整个空间。可以使用-Xmx选项指定保留空间的大小。如果-Xms参数的值小于-Xmx参数的值,则不会立即将所有保留的空间提交给虚拟机。图中未提交的空间被标记为“virtual”。堆的不同部分,即老一代和年轻一代,可以根据需要增长到虚拟空间的极限。

有些参数是堆的一部分与另一部分的比值。例如,参数XX:NewRatio表示老一代与年轻一代的相对大小。

Description of Figure 4-1 follows

图片说明:
    这个数字由一排六个矩形组成。这些矩形是按这个顺序标记的。
        1.Eden
        2.Survivor
        3.Survivor
        4.Virtual
        5.Old
        6.Virtual

    矩形组标记如下:
        Total size: 矩形1到6
        Committed vs. Virtual:Committed矩形由1到3和5组成;Virtual由矩形4和6组成。
        Old to Young ratio:old由矩形1到4组成;young由矩形5和6组成。
        Eden to Survivor space ratio: Eden是矩形1; Survivor是矩形2。

1.2.堆大小的默认值 

默认情况下,虚拟机在每个收集器上增加或减少堆,以将每个收集器上的活动对象的空闲空间比例保持在特定范围内。

这个目标范围通过参数-XX:MinHeapFreeRatio=<minimum>和-XX:MaxHeapFreeRatio=<maximum>来设置百分比,总大小下以Xms<min>为界,上以Xmx<max>为界。途中展示了64位Solaris操作系统(SPARC Platform Edition)的缺省值。

参数 默认值
MinHeapFreeRatio 40
MaxHeapFreeRatio 70
-Xms 6656k
-Xmx calculated

使用这些参数,如果分代中的可用空间百分比低于40%,则分代将扩展为40%的可用空间,直到达到分代的最大允许大小。相同地,如果空闲空间超过70%,那么将收缩分代,减少只有70%的空闲空间。受制于该分代的最小尺寸。

如表所示,默认的最大堆大小是JVM计算的值。 Java SE中用于Parallel收集器的计算现在用于所有垃圾收集器。 部分计算是64位平台的最大堆大小的上限。 请参见并行收集器默认堆大小。 对于客户端JVM,也存在类似的计算,这导致最大堆大小小于服务器JVM。

以下是有关服务器应用程序的堆大小的一般准则:
                   • 除非遇到停顿问题,否则请尽量为虚拟机分配尽可能大的内存。默认大小通常都太小。
                   • 将Xms和-Xmx设置为相同的值可关闭虚拟机的大小决策,以提高可预测性。但是,如果你做出错误的选择,则虚拟机无法补偿。
                   • 通常,在增加处理器数量的同时也要同步增加内存,因为分配可以并行化。

1.3.通过最小化Java堆大小来节省动态占用空间

如果需要最小化应用程序的动态内存占用(执行期间消耗的最大RAM),那么可以通过最小化Java堆大小来实现这一点。Java SE嵌入式应用程序可能需要这样做。

通过降低-XX:MaxHeapFreeRatio和-XX:MinHeapFreeRatio的值来最小化Java堆大小。将-XX:MaxHeapFreeRatio降低到10%或-XX:MinHeapFreeRatio成功地降低堆大小,而没造成太多性能下降;然而,根据应用程序,结果可能会有很大的不同。尝试使用不同的值,直到它们尽可能低,但仍保持可接受的性能。

此外,您还可以指定-XX:-ShrinkHeapInSteps,它可以立即将Java堆减小到目标大小(由参数-XX:MaxHeapFreeRatio指定)。使用此设置可能会导致性能下降。默认情况下,Java运行时增量地将Java堆减小到目标大小;这个过程需要多个垃圾收集周期。

二.年轻代(Young Generation)

除了总可用内存之外,影响垃圾收集性能的第二大因素是用于年轻代的堆的比例。

年轻代越大,发生minor收集的频率越低。然而,对于有限制的堆大小,较大的年轻代意味着较小的老年代,这将增加major 收集的频率。最优选择取决于应用程序分配的对象的生存期分布。

2.1.年轻代(Young Generation)大小参数

默认情况下,年轻代的大小由参数-XX:NewRatio控制。

例如,设置-XX:NewRatio = 3意味着年轻代和老代之间的比例是1:3。 换句话说,伊甸园(eden)和幸存空间(survivor spaces)的组合大小将是总堆大小的四分之一。

参数-XX:NewSize和-XX:MaxNewSize从下(小)到上(大)限制了年轻代的大小。 将它们设置为相同的值可以修复年轻代,正如将-Xms和-Xmx设置为相同的值可以修复总堆大小一样。 这比以-XX:NewRatio允许的整数倍更精细的粒度调整年轻代有用。

2.2.幸存空间(survivor spaces)大小

您可以使用参数-XX:SurvivorRatio来调整幸存空间(survivor spaces)的大小,但这通常对性能不重要。

例如,-XX:SurvivorRatio=6将伊甸园(eden)和幸存空间(survivor spaces)之间的比率设置为1:6。换句话说,每个幸存空间(survivor spaces)将是伊甸园(eden)大小的六分之一,也就是年轻代大小的八分之一(不是七分之一,因为有两个幸存者空间)。

如果幸存空间(survivor spaces)太小,那么复制收集时会直接溢出到旧一代。 如果幸存空间(survivor spaces)太大,那么它们(空着的部分)就没用了。 在每次垃圾收集时,虚拟机会选择一个阈值编号,该阈值编号是对象在旧版之前可以复制的次数。 选择此阈值的目的是为了使幸存空间保持半满。你可以使用日志配置命令Xlog:gc,age ,可显示此阈值和新一代对象的年龄。 它对于观察应用程序的生命周期分布也很有用。

 下表提供了64位Solaris的缺省值:

Option Default Value

-XX:NewRatio

2

-XX:NewSize

1310 MB

-XX:MaxNewSize

not limited

-XX:SurvivorRatio

8

年轻代的最大大小由总堆的最大大小和-XX:NewRatio参数的值计算。MaxNewSize参数的“not limited”默认值意味着计算值不受-XX:MaxNewSize的限制,除非在命令行中指定了-XX:MaxNewSize的值。

以下是服务器应用程序的一般准则:

        1.首先,确定可以为虚拟机提供的最大堆大小。然后,根据年轻代的大小确定性能指标,以找到最佳设置。
                             1.1.注意,最大堆大小应该始终小于机器上安装的内存大小,以避免过多的页面错误和抖动。

        2.如果总堆大小是固定的,那么增加年轻代的大小需要减少老年代的大小。保持老年代的大小足够大,可以在任何时候容纳应用程序使用的所有实时数据,加上一定数量的闲置空间(10到20%或更多)。

        3.遵守之前对老年代的约束:

                  3.1.给年轻代留下足够的内存。
                             3.2.随着处理器数量的增加同步增加年轻代的大小,因为分配可以并行化。

猜你喜欢

转载自blog.csdn.net/weixin_37519752/article/details/89399612
今日推荐