一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
5.垃圾回收调优
查看虚拟机参数命令,可以根据参数去查询具体的信息
"D:\JAVA\JDK8.0\bin\java" -XX:+PrintFlagsFinal -version | findstr "GC"
- 掌握 GC 相关的 VM 参数,会基本的空间调整
- 掌握相关工具
- 明白一点:调优跟应用、环境有关,没有放之四海而皆准的法则
(1)调优领域
- 内存
- 锁竞争
- CPU占用
- IO
- GC
(2)确定目标
低延迟/高吞吐量? 选择合适的GC
- CMS G1 ZGC
- ParallelGC
- Zing
(3)最快的GC
最快的GC是不发生GC 首先排除减少因为自身编写的代码而引发的内存问题
- 数据是不是太多?
- resultSet = statement.executeQuery("select * from 大表 limit n")
- 数据表示是否太臃肿
- 对象图
- 对象大小
- 是否存在内存泄漏
- static Map map =
- 软
- 弱
- 第三方缓存实现
(4)新生代调优
新生代的特点
- 所有的new操作分配内存都是非常廉价的 TLAB
- 死亡对象回收零代价
- 大部分对象用过即死(朝生夕死)
- MInor GC 所用时间远小于Full GC
新生代内存越大越好么?
-
不是
- 新生代内存太小:频繁触发Minor GC,会STW,会使得吞吐量下降
- 新生代内存太大:老年代内存占比有所降低,会更频繁地触发Full GC。而且触发Minor GC时, 清理新生代所花费的时间会更长
-
新生代内存设置为内容纳[并发量*(请求-响应)]的数据为宜
-
幸存区大到能保留【当前活跃对象+需要晋升对象】
-
晋升阈值配置得当,让长时间存活对象尽快晋升
-XX:MaxTenuringThreshold=threshold -XX:+PrintTenuringDistributionDesired survivor size 48286924 bytes, new threshold 10 (max 10) - age 1: 28992024 bytes, 28992024 total - age 2: 1366864 bytes, 30358888 total - age 3: 1425912 bytes, 31784800 total ...
(5)老年代调优
以 CMS 为例
- CMS 的老年代内存越大越好
- 先尝试不做调优,如果没有 Full GC 那么已经...,否则先尝试调优新生代
- 观察发生 Full GC 时老年代内存占用,将老年代内存预设调大 1/4 ~ 1/3
-XX:CMSInitiatingOccupancyFraction=percent
(6)案例
- 案例1 Full GC 和 Minor GC频繁
- 案例2 请求高峰期发生 Full GC,单次暂停时间特别长 (CMS)
- 案例3 老年代充裕情况下,发生 Full GC (CMS jdk1.7)