
jvm-05
发布日期:2021-05-08 05:28:20
浏览次数:11
分类:原创文章
本文共 3118 字,大约阅读时间需要 10 分钟。
- 垃圾收集发生的时机
- GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。 当然,我们可以手动进行垃圾回收,
比如调用System.gc()方法通知JVM进行一次垃圾回收,但是具体什么时刻运行也无法控制。也就是说
System.gc()只是通知要回收,什么时候回收由JVM决定。 但是不建议手动调用该方法,因为消耗的资源比较
大。 - 一般以下几种情况会发生垃圾回收
- Full GC = Minor GC+Major GC +MetaSpace GC
- 当Eden区或者S区不够用
- 老年代空间不够用
- 方法区空间不够用了
- System.gc()
- GC是由JVM自动完成的,根据JVM系统环境而定,所以时机是不确定的。 当然,我们可以手动进行垃圾回收,
GC日志文件分析工具
- gceasy
- https://gceasy.io
- 可以比較不同的垃圾收集器的吞吐量和停顿时间
- 比如打开cms-gc.log和g1-gc.log
- GCViewer
调优
- 是否选用G1垃圾收集器的判断依据
- https://docs.oracle.com/javase/8/docs/technotes/guides/vm/G1.html#use_cases
- 50%以上的堆被存活对象占用
- 对象分配和晋升的速度变化非常大
- 垃圾回收时间比较长
调优步骤
- 使用G1GC垃圾收集器: -XX:+UseG1GC
- 修改配置参数,获取到gc日志,使用GCViewer分析吞吐量和响应时间
Throughput Min Pause Max Pause Avg Pause GC count 99.16% 0.00016s 0.0137s 0.00559s 12
- 调整内存大小再获取gc日志分析
-XX:MetaspaceSize=100M-Xms300M-Xmx300M
设置堆内存大小后,获取gc日志,使用GCViewer分析吞吐量和响应时间
Throughput Min Pause Max Pause Avg Pause GC count 98.89% 0.00021s 0.01531s 0.00538s 12
- 调整最大停顿时间
-XX:MaxGCPauseMillis=20 设置最大GC停顿时间指标
Throughput Min Pause Max Pause Avg Pause GC count 98.96% 0.00015s 0.01737s 0.00574s 12
- 启动并发GC时堆内存占用百分比
-XX:InitiatingHeapOccupancyPercent=45 G1用它来触发并发GC周期,基于整个堆的使用率,而不只是某一代内存的 使用比例。值为 0 则表示“一直执行GC循环)'. 默认值为 45 (例如, 全部的 45% 或者使用了45%).
获取到gc日志,使用GCViewer分析吞吐量和响应时间
Throughput Min Pause Max Pause Avg Pause GC count 98.11% 0.00406s 0.00532s 0.00469s 12
官网建议
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/g1_gc_tuning.html#recommendations
- 不要手动设置新生代和老年代的大小,只要设置整个堆的大小
G1收集器在运行过程中,会自己调整新生代和老年代的大小 其实是通过adapt代的大小来调整对象晋升的速度和年龄,从而达到为收集器设置的暂停时间目标 如果手动设置了大小就意味着放弃了G1的自动调优
- 好处:吞吐量增减,GC次数减少
- 不好: 停顿时间变大–>Client较长时间停顿。原因:每一次垃圾回收的时候,周期就会拉长。
- 不断调优暂停时间目标(停顿时间不要太严格)
一般情况下这个值设置到100ms或者200ms都是可以的(不同情况下会不一样),但如果设置成50ms就不太合理。暂停 时间设置的太短,就会导致出现G1跟不上垃圾产生的速度。最终退化成Full GC。所以对这个参数的调优是一个持续 的过程,逐步调整到最佳状态。暂停时间只是一个目标,并不能总是得到满足。
优势:停顿时间能够被控制了
劣势:GC次数增加了(原因:一次回收或标志没有标志完,只能下一次回收,下一次还没来得及回收或标志 再等下一次)
- 使用-XX:ConcGCThreads=n来增加标记线程的数量
IHOP如果阀值设置过高,可能会遇到转移失败的风险,比如对象进行转移时空间不足。如果阀值设置过低,就会使标 记周期运行过于频繁,并且有可能混合收集期回收不到空间。 IHOP值如果设置合理,但是在并发周期时间过长时,可以尝试增加并发线程数,调高ConcGCThreads。
-
MixedGC调优
- -XX:InitiatingHeapOccupancyPercent (堆内存使用占比,即达到某个百分比才触发回收)
- -XX:G1MixedGCLiveThresholdPercent
- -XX:G1MixedGCCountTarger
- -XX:G1OldCSetRegionThresholdPercent
-
适当增加堆内存大小
G1 和cms的区别
- cms:老年代
- 整体上使用标志- 清除法,空间碎片
- G1:适用新生代和老年代
- Regon,对堆内存进行逻辑分区
- 标志-整理,减少空间碎片
- 1 收集方式:Garbage First,优先会收集垃圾比较多的区域
- 2 CMS:新生代,或者是老年代Card Table 引用了谁【不用全盘扫描整个老年代】,G1,Remembered Set Rset(谁引用了我,也不用全盘扫描,方式不一样)
- 3 G1设计的初衷:以前的垃圾收集器:1必须扫描老年代,新生代和老年代 空间连续
- 4 G1 产生:多核,大内存
- 5 G1停顿时间
- 6 CSet:一组被回收的分区的集合,存活对象移动到另外的分区 CSet <1%
如果Full GC频繁怎么办?怎样减少Full GC?
- Young:Old Young适当增加,每一秒都产生大量对象,不让他过去老年代
GC的次数频繁,你会怎么办
- 为什么会频繁?GC次数多,CPU使用率高了
- 打印出gc 日志–>minor gc/major gc?,结合工具看
- 内存空间少了?适当增加对内存空间
- 选择垃圾收集器不合适、如果是是大内存的空间,可以选择G1
- 是否是set pause time strict/堆内存使用了 occupancy(启动并发GC时堆内存占用百分比) 停顿时间过于严格
cup 持续飙升
- 为什么CPU升高
- top 看进程id,jstack/jinfo/jmap
- 并发量太高?
- 集群
- mq
- 业务层面 死锁?
- 并发量太高?
oom
- dump文件
- 分析dump文件工具/MAT/其他工具
内存泄漏和内存溢出oom区别
- 内存泄漏:内存得不到有效回收
- 累计一定程度的内存泄漏对象导致 oom
方法区的回收主要是回收什么内容
- 方法区里面存储的内容 是,类信息,静态变量,常量等
- 没有用的类的信息、常量
- 类信息什么时候能够被回收?:
- 1 堆里面不再有该类对象
- 2 加载该类的ClassLoader已经被回收了
- 3 java.lang.Class对象也不再有任何地方引用了,反射也不能使用
- 满足上述条件可以回收,不一定一定回收
不可达的对象一定就被回收吗?
- 不可达对象—>finalize()---->可以变成 不是垃圾的对象
Young GC 会stop the world吗
- YoungGC:新生代的GC
- 不管什么 GC,都会有 stop-the-world,只是发生时间的长短
发表评论
最新留言
初次前来,多多关照!
[***.217.46.12]2025年03月27日 21时55分15秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
VTK:Medical之MedicalDemo2
2019-03-05
VS配置属性表,保存Opencv配置信息
2019-03-05
c语言(基本数据类型)实参与形参传值 用汇编理解
2019-03-05
输入端噪声容限
2019-03-05
vue——this.$route 与 this.$router
2019-03-05
基于单片机可控音乐流水灯控制设计-全套资料
2019-03-05
基于单片机简易信号误差分析设计-全套资料
2019-03-05
基于单片机简易洗衣机系统仿真设计-全套资料
2019-03-05
基于单片机简易脉搏测量仪系统设计-毕设课设资料
2019-03-05
基于单片机八层电梯系统控制设计-毕设课设资料
2019-03-05
并发框架下的“基础类型”——浅析基本类型、ThreadLocal、原子类的线程安全机制
2019-03-05
Android Studio同步Gradle失败的解决办法
2019-03-05
VHDL代码风格
2019-03-05
C++系列7:回调函数
2019-03-05
图像处理系列1.skimage
2019-03-05
好用的拼图小程序,图作妖
2019-03-05
读取二进制存储信息,将低位二进制存储转换为高位存储
2019-03-05
Hibernate操作Blob,将Blob转换为String
2019-03-05
Object Clone
2019-03-05