IT评测·应用市场-qidao123.com
标题:
读Java性能权威指南(第2版)笔记18_垃圾回收E
[打印本页]
作者:
不到断气不罢休
时间:
2023-3-16 07:12
标题:
读Java性能权威指南(第2版)笔记18_垃圾回收E
1. 回收
1.1. 找到不使用的对象
1.2. 释放它们的内存
1.3. 压缩堆
1.4. 合在一起称为回收
2. Throughput回收器
2.1. 工作细节比较简单
2.1.1. 可以在同一个GC周期内完成回收
2.1.2. 在单次操作过程中回收新生代或老年代
2.2. Minor GC
2.2.1. 当Eden空间被填满时,新生代回收就会发生
2.2.2. 新生代回收会将所有的对象移出Eden空间
2.2.2.1. Eden空间一般是空的
2.2.2.2. 不认为它被压缩了
2.2.3. 另一些被移到老年代
2.2.4. 还有大量对象因不再使用而被丢弃
2.3. Full GC
2.3.1. 老年代回收会将新生代中的所有对象释放出来
2.3.2. 只有老年代中还剩下活跃引用的对象
2.3.3. 所有这些对象占用的空间都会被压缩
2.3.3.1. 只占用老年代的开始部分
2.3.3.2. 其余部分是空闲的内存空间
2.4. 优化
2.4.1. 围绕停顿时间进行的
2.4.2. 权衡
2.4.2.1. 时间和空间的取舍
2.4.2.1.1. 更大的堆会消耗机器上更多的内存
2.4.2.1.2. 应用程序会有更高的吞吐量
2.4.2.2. 执行GC所需的时间长度
2.4.2.2.1. 增加堆的大小可以减少Full GC停顿的次数
2.4.2.2.2. GC时间较长,可能延长平均响应时间
2.4.2.2.3. 为了缩短GC停顿时间
2.4.2.2.3.1. 将更多的堆分配给新生代而不是老年代
2.4.2.2.3.2. 会增加老年代回收的频率
2.5. 自适应大小
2.5.1. 重新调整堆(和代)的大小,以实现其停顿时间的目标
2.5.1.1. 并不总是堆越大就越好
2.5.2. 当给定的停顿时间目标不切实际时,应用程序的行为会更糟糕
2.5.3. -XX:MaxGCPauseMillis=N
2.5.3.1. 用于设定应用程序可接受的最大停顿毫秒数
2.5.3.2. 默认情况下,不设置这个标志
2.5.3.3. 适用于Minor GC和Full GC
2.5.3.4. 如果使用了一个非常小的值,那么应用程序最终会得到一个非常小的老年代
2.5.3.4.1. 导致JVM非常频繁地执行Full GC,应用程序的性能会很糟糕
2.5.4. GC中花费总时间3%到6%的应用程序,运行效果相当好
2.5.5. -XX:GCTimeRatio=N
2.5.5.1. 设定你希望应用程序在GC上花费的时间(相对于应用程序线程应该运行的时间)
2.5.5.2. 标志的默认设置很适用
2.5.5.2.1. 默认值是99
2.5.5.2.2. 在没有其他目标的情况下,推荐时间比例设置为19(GC时间占5%)
2.5.5.3. ThroughputGoal=1-(1÷ (1+GCGCTimeRatio))
3. CMS回收器
3.1. 已废弃
3.2. 3个基本操作
3.2.1. 回收新生代(同时暂停所有的应用程序线程)
3.2.2. 运行并发周期来清理老年代的数据
3.2.3. 如果有必要,执行Full GC来压缩老年代
3.3. 对象会从Eden空间移到一个Survivor空间(Survivor空间满了之后就移动到老年代)
3.4. 默认情况下,CMS不会回收元空间
3.5. 除非发生Full GC,否则永远不会调整新生代的大小
3.6. CMS周期的停顿一般比新生代停顿短得多,特定的应用程序可能对这些额外的停顿并不敏感
3.7. 并发周期
3.7.1. 初始标记(initial mark)阶段开始
3.7.1.1. 会暂停所有应用程序线程
3.7.2. 标记(mark)阶段
3.7.2.1. 不会暂停应用程序线程
3.7.3. 预清理(preclean)阶段
3.7.3.1. 和应用程序线程同时运行
3.7.4. 重新标记(remark)阶段
3.7.4.1. 不是并发的,会暂停所有的应用程序线程
3.7.5. 可中止的预清理(abortable preclean)阶段
3.7.5.1. 会等到新生代被占用50%后才开始
3.7.5.2. 阶段的中止,这是停止这个阶段的唯一方式
3.7.6. 清除(sweep)阶段
3.7.7. 并发重置(reset)阶段
3.7.7.1. 最后一个阶段
3.8. 当发生新生代回收,但是老年代中并没有足够的空间容纳预计要晋升的对象时,CMS会执行Full GC
3.8.1. 所有的应用程序线程都会被暂停
3.8.2. 该操作是单线程的
3.8.2.1. 它耗时如此之长的原因之一
3.8.2.2. 并发模式失败随着堆的增长而影响更大的原因之一
3.8.3. 这种并发模式失败是CMS被废弃的主要原因
3.9. 老年代中有足够的空间容纳晋升对象,但空闲空间是碎片化的,所以对象晋升还是会失败
3.9.1. CMS无法晋升对象,因为老年代是碎片化的
3.9.2. 要晋升的内存量比CMS预期的要大,这种情况更少
3.10. CMS的日志可能显示了Full GC,但是没有任何常规的并发GC消息
3.10.1. 当元空间被填满并需要回收时,这种情况就会发生
3.10.2. CMS不会回收元空间,所以如果它被填满了,就需要Full GC来丢弃任何未被引用的类
3.11. 优化
3.11.1. 确保不会发生并发模式失败或晋升失败
3.11.1.1. 避免并发模式失败是实现CMS最佳性能的关键
3.11.1.2. 避免这些失败的最简单的方法(在可能的情况下)是增加堆的大小
3.11.2. 当执行新生代回收时,CMS计算出没有足够的空间容纳这些将晋升到老年代的对象,所以会先回收老年代
3.11.3. 让老年代空间更大一些,要么调整新生代和老年代的比例,要么增加更多的堆空间
3.11.4. 更频繁地运行后台线程
3.11.4.1. 提早开始并发周期
3.11.4.2. -XX:CMSInitiatingOccupancyFraction=N
3.11.4.2.1. 默认为70
3.11.4.2.1.1. CMS并发周期会在老年代被占用70%时开始
3.11.4.2.2. 不要将该值设置得低于堆中的活跃数据量,至少应加上10%到20%
3.11.4.3. -XX:+UseCMSInitiatingOccupancyOnly
3.11.4.3.1. 默认情况下false
3.11.4.4. 如果两个都设置了,CMS就会只根据老年代的填充比例来决定何时启动后台线程
3.11.4.5. 此处的占用率是基于老年代的,而不是整个堆
3.11.5. 使用更多的后台线程
3.11.5.1. -XX:ConcGCThreads=N
3.11.5.1.1. 增加后台线程数量
3.11.5.1.2. ConcGCThreads = (3 + ParallelGCThreads) / 4
3.11.5.1.3. 能比G1 GC早一步增加ConcGCThreads的值
3.12. MaxGCPauseMllis=N
3.12.1. 见前文
3.13. GCTimeRatio=N
3.13.1. 见前文
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/)
Powered by Discuz! X3.4