读Java性能权威指南(第2版)笔记20_垃圾回收G,
读Java性能权威指南(第2版)笔记20_垃圾回收G,
1. Survivor空间
1.1. 新生代被划分为两个Survivor空间和一个Eden空间的原因
-
1.1.1. 刚刚被创建并且还在使用中,所以不能被回收,但它们的寿命并没有长到足以进入老年代
-
1.1.2. 仍在新生代中的对象有额外的机会被回收,而不是晋升到(并填满)老年代
1.2. 首次新生代回收期间,对象从Eden空间移动到Survivor空间0
1.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. 不能修改
1.1.1. 刚刚被创建并且还在使用中,所以不能被回收,但它们的寿命并没有长到足以进入老年代
1.1.2. 仍在新生代中的对象有额外的机会被回收,而不是晋升到(并填满)老年代
1.4.1. Survivor空间非常小,当目标Survivor空间在新生代回收过程中被填满时,Eden空间中剩余的任何活跃对象都会被直接移入老年代
1.4.2. 对于停留在Survivor空间中的对象,其经历的GC周期数量有限制,超过这个限制的对象会被直接移入老年代
- 1.4.2.1. 晋升阈值(tenuring threshold)
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.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.1. 将SurvivorRatio设置为期望的值
1.7.2. 禁用UseAdaptiveSizePolicy标志
1.9.1. Throughput回收器和G1 GC回收器默认是7
1.9.2. CMS默认是6
1.10.1. 最大阈值
1.10.2. Throughput回收器和G1 GC回收器的默认最大阈值是15
1.10.3. CMS的是6
1.11.1. 永远晋升
1.11.2. 相当于把MaxTenuringThreshold设为0
1.11.3. 对象总是会晋升到老年代,而不是存储在Survivor空间中
1.11.4. 默认是false
1.12.1. 永不晋升
1.12.2. 将初始晋升阈值和最大晋升阈值认为是无穷大
1.12.3. 只要Survivor空间仍有空闲,任何对象都不会晋升到老年代
1.12.4. 默认也是false
1.12.5. 防止JVM降低晋升阈值
1.13.1. 在JDK 8中
1.13.2. 将对象年龄分布添加到GC日志中
1.13.3. 默认是false
1.14.1. 在JDK11中
1.14.2. 将对象年龄分布添加到GC日志中
1.14.3. 默认是false
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. 不能修改
用户点评