论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
软件与程序人生
›
后端开发
›
Java
›
读Java性能权威指南(第2版)笔记18_垃圾回收E ...
读Java性能权威指南(第2版)笔记18_垃圾回收E
花瓣小跑
金牌会员
|
2023-3-16 07:14:40
|
显示全部楼层
|
阅读模式
楼主
主题
976
|
帖子
976
|
积分
2928
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. 见前文
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
花瓣小跑
金牌会员
这个人很懒什么都没写!
楼主热帖
【电脑配置】新电脑买回来怎么配置? ...
数理逻辑第4-5章
使用axios发送post请求上传文件(multip ...
应急响应(总)
最简单易懂的ios p12证书 和描述文件的 ...
【网络攻防】常见的网络攻防技术——黑 ...
使用 Mypy 检查 30 万行 Python 代码, ...
计算机网络原理(谢希仁第八版)第六章课 ...
gorm操作sqlite3,高并发读写如何避免 ...
XXE漏洞学习
标签云
运维
CIO
存储
服务器
浏览过的版块
开源技术
DevOps与敏捷开发
快速回复
返回顶部
返回列表