1.Survivor空间1.1.新生代被划分为两个Survivor空间和一个Eden空间的原因

  • 1.1.1.刚刚被创建并且还在使用中,所以不能被回收,但它们的寿命并没有长到足以进入老年代

  • 1.1.2.仍在新生代中的对象有额外的机会被回收,而不是晋升到(并填满)老年代

1.2.首次新生代回收期间,对象从Eden空间移动到Survivor空间01.3.下次回收时,活跃对象会从Survivor空间0和Eden空间移动到Survivor空间1

  • 1.3.1.此时Eden空间和Survivor空间0完全是空的

1.4.被移入老年代场景

  • 1.4.1.Survivor空间非常小,当目标Survivor空间在新生代回收过程中被填满时,Eden空间中剩余的任何活跃对象都会被直接移入老年代

  • 1.4.2.对于停留在Survivor空间中的对象,其经历的GC周期数量有限制,超过这个限制的对象会被直接移入老年代

    • 1.4.2.1.晋升阈值(tenuring threshold)

1.5.-XX:InitialSurvivorRatio=N

  • 1.5.1.初始大小

  • 1.5.2.默认值为8

    • 1.5.2.1.新生代的10%
  • 1.5.3.survivor_space_size = new_size / (initial_survivor_ratio + 2)

1.6.-XX:MinSurvivorRatio=N

  • 1.6.1.最大值

  • 1.6.2.默认情况为3

    • 1.6.2.1.新生代的20%
  • 1.6.3.maximum_survivor_space_size = new_size / (min_survivor_ratio + 2)

  • 1.6.4.最小的比例可以得到最大的Survivor空间

1.7.要让Survivor空间保持固定大小

  • 1.7.1.将SurvivorRatio设置为期望的值

  • 1.7.2.禁用UseAdaptiveSizePolicy标志

1.8.XX:TargetSurvivorRatio=N

  • 1.8.1.GC之后Survivor空间的占用率

1.9.-XX:InitialTenuringThreshold=N

  • 1.9.1.Throughput回收器和G1 GC回收器默认是7

  • 1.9.2.CMS默认是6

1.10.-XX:MaxTenuringThreshold=N

  • 1.10.1.最大阈值

  • 1.10.2.Throughput回收器和G1 GC回收器的默认最大阈值是15

  • 1.10.3.CMS的是6

1.11.-XX:+AlwaysTenure标志

  • 1.11.1.永远晋升

  • 1.11.2.相当于把MaxTenuringThreshold设为0

  • 1.11.3.对象总是会晋升到老年代,而不是存储在Survivor空间中

  • 1.11.4.默认是false

1.12.-XX:+NeverTenure

  • 1.12.1.永不晋升

  • 1.12.2.将初始晋升阈值和最大晋升阈值认为是无穷大

  • 1.12.3.只要Survivor空间仍有空闲,任何对象都不会晋升到老年代

  • 1.12.4.默认也是false

  • 1.12.5.防止JVM降低晋升阈值

1.13.-XX:+PrintTenuringDistribution标志

  • 1.13.1.在JDK 8中

  • 1.13.2.将对象年龄分布添加到GC日志中

  • 1.13.3.默认是false

1.14.Xlog参数加上age=debug或age=trace命令

  • 1.14.1.在JDK11中

  • 1.14.2.将对象年龄分布添加到GC日志中

  • 1.14.3.默认是false

2.分配大对象2.1.线程本地分配缓冲区

  • 2.1.1.thread-local allocation buffer,TLAB

  • 2.1.2.默认是开启的

  • 2.1.3.所有的GC算法都要考虑TLAB的大小

  • 2.1.4.它们很小,所以TLAB内不能分配大对象

2.2.TLAB的大小取决于3个因素

  • 2.2.1.应用程序中的线程数量

  • 2.2.2.Eden空间的大小

  • 2.2.3.线程的分配速率

2.3.从TLAB的参数优化中受益场景

  • 2.3.1.分配很多大对象的应用程序

  • 2.3.2.和Eden空间的大小相比,线程数量相对较多的应用程序

2.4.-XX:-UseTLAB禁用

  • 2.4.1.可以提升性能,禁用它们永远是个坏主意

2.5.大量的分配发生在TLAB之外

  • 2.5.1.减小分配对象的大小

  • 2.5.2.调整与TLAB大小相关的参数

2.6.JFR工具2.7.-XX:+PrintTLAB标志

  • 2.7.1.在JDK 8

2.8.tlab*=trace

  • 2.8.1.在JDK 11

2.9.调整TLAB的大小

  • 2.9.1.-XX:TLABSize=N标志

    • 2.9.1.1.默认值为0

    • 2.9.1.2.显式地设置TLAB的大小

    • 2.9.1.3.只能设置TLAB的初始大小

  • 2.9.2.-XX:-ResizeTLAB标志

    • 2.9.2.1.默认是true

    • 2.9.2.2.防止每次GC时都调整大小

  • 2.9.3.调整TLAB以提升性能的最简单的方法,也是唯一有用的方法

2.10.-XX:TLABWasteTargetPercent

  • 2.10.1.阈值

  • 2.10.2.默认是TLAB大小的1%

  • 2.10.3.动态的

2.11.-XX:TLABWasteIncrement=N

  • 2.11.1.增幅

  • 2.11.2.默认是4

2.12.-XX:MinTLABSize=N

  • 2.12.1.TLAB的最小值

  • 2.12.2.默认为2 KB

2.13.TLAB的最大值略小于1 GB

  • 2.13.1.可以容纳一个整数数组的最大空间,数组大小向下取整以对齐对象

  • 2.13.2.不能修改