Jvm垃圾回收器及参数

一、垃圾回收器

1、serialGC

(1)工作原理:

最基础的垃圾回收器
使用单线程进行标记、清理、回收,在fullGC时,应用会stop-the-world,因此有较长的等待时间

(2)优点:

实现简单,适用于较小的环境
单线程回收

(3)缺点:

停顿时间长,性能差不适合高并发或需要低延迟的系统

2、Parallel GC:

(1)工作原理:

jdk8的默认垃圾回收器,专注与吞吐量, 即减少GC时间,相对增加应用现线程的执行时间
在fullGC时,会使用多线程并执行垃圾回收的各个阶段,从而提高效率

(2)优点:

吞吐量高
简单、直接、适用于对延迟要求不高的系统
多线程回收可以减少GC时间,适用于多核机器

(3)缺点:

停顿时间较长,尤其是发生FullGC时,导致长时间停顿
对低延迟较高的系统不适用

(4)适用的业务场景:

日志处理、定时任务,要求吞吐量,能容忍长时间的停顿

3、CMS:

(1)工作原理:

针对低停顿场景设计,通过并发标记和并发清理减少FullGC停顿时间
<1>初始标记阶段
标记处GCroots能直接关联到的对象,会短暂STW,由于直接关联对象比较小,所以这里速度非常快
<2>并发标记阶段
从GCroots直接关联的对象开始遍历所有对象的过程,耗时较长但不需要停顿用户线程
<3>重新标记阶段
对新产生的对象重新标记,会STW,时间比初始标记稍长一些,但远比并发标记阶段时间短。由于在并发阶段用户线程个垃圾回收线程同时或交叉运行。
新产生的对象:在标记期间用户程序继续运作产生一部分对象未被标记
<4>并发清楚阶段
清理已经被标记死亡别的对象,释放内存空间,用户线程、垃圾回收线程并发执行

(2)优点:

低停顿,比parallel Gc更适合对响应时间更敏感的应用
避免fullGC,尤其在大内存环境下
并发标记,回收效率高

(3)缺点:

在fullGC时,停顿时间较长,尤其在堆内存较大时,无法避免长时间的STW
较为复杂,调优难度大
对CPU消耗较大
会触发fullGC,serial会作为默认的垃圾回收器,单线程执行整个回收过程
老年代内存不足:当老年代的内存不够分配新的对象时
内存碎片化:当老年代的内存不够分配新的对象时

(4)适合场景:

金融交易系统:对实时性要求高,尽量减少停顿的场景
在线支付系统:响应时间要求严格,内存不算非常大
大型WEB服务,对响应时间要求高

4、G1 GC:

(1)工作原理:

为大内存系统(例如内存>8GB)提供低停顿,将堆内存分为多个区域,并采用增量方式进行回收,G1可以根据设定的目标停顿时间,动态调整回收策略。
主要采用了两种垃圾回收模式:Young GC和Mixed GC
<1>Young GC:主要针对年轻代区域的垃圾回收
当所有Eden区使用率达到最大阀值(默认60%),会触发一次Young GC,
回收Eden区和Survivor区,复制移动到另外的Survivor幸存者(年龄+1)或Old老年代区(提前晋升的)
<2>Mixed GC(混合回收):Mixed GC是G1垃圾回收器独有的,也称混合回收,针对年轻代和部分老年代区域的垃圾回收。
当老年代的占有率达到阀值(默认45%)或年轻代被分配大对象时,会触发一次Mixed GC,
回收所有年轻代和一部分老年代区(选取的策略是垃圾对象最多的老年代区域,确保释放更多内存空间,即回收价值高的),控制最大暂停时间。
<3>混合回收分为如下步骤:
初始标记
并发标记
最终标记:只管漏标,不管新创建、不再关联的对象。这里使用的算法远比CMS的快
并发清理:G1对老年代的清理会选择存活度最低的区域来进行回收,这样可以保证回收效率最高。最后清理阶段使用复制算法,不会产生内存碎片。
如果清理过程中发现没有足够的空区域存放转移的对象,会出现FullGC。单线程执行标记-整理算法,会STW

(2)优点:

低停顿
更高的回收效率,特别是大内存环境下
适应性强,根据业务负载自动调整回收策略

(3)缺点:

相比paraller吞吐量较低,但可以通过配置来平衡吞吐量和停顿时间
初始配置相对复杂,根据业务需求精细调优

(4)业务场景:

大型微服务系统,要平衡吞吐量和低延迟的场景,适用于大内存和高并发环境。
大数据分析:需要处理大量数据且对响应时间要求高的场景
大型WEB应用

5、CMS和G1区别:

(1)设计目标:

CMS目标:降低 停顿时间,特别是 老年代(Old Generation) 的回收时停顿时间。
G1目标:提供 可预测的停顿时间,尤其是大内存系统。

(2)FullGC发生频率

当 Old Generation 空间不足、内存碎片严重时,CMS 会触发 Full GC会STW,导致较长停顿时间
Full GC 发生频率:G1 通过 区域化内存管理,使得 Full GC 发生的几率大大降低。即便发生了 Full GC,G1 也能够更加精确地控制停顿时间。

(3)内存碎片化

CMS可能会导致 内存碎片化;G1可以有效避免

(4)适用的堆内存大小

CMS:适合 内存较小(< 8GB)的应用,尤其是在对低停顿要求较高的情况下。
G1:适合 大内存(> 8GB)的应用,特别是要求 可预测的停顿时间 或者在 低延迟(Low Latency)场景下的应用。

(5)使用 CMS 的场景:

堆内存较小(< 8GB);
对低停顿有一定要求,但负载较小;
内存碎片不是特别明显的问题。

(6)使用 G1 的场景:

堆内存较大(> 8GB);
对 可预测的停顿时间 有高要求;
需要 避免内存碎片,对大内存的管理和回收更有要求;
需要灵活控制垃圾回收的停顿时间(如低延迟系统)。

二、设置JVM参数

1、设置堆内存:

初始值:-Xms4g
最大值:-Xmx8g

2、设置元区间(Meta)最大值

-XX:MaxMetaspaceSize=2g

3、设置单个线程栈的大小:

-Xss1m

4、指定GC算法:

-XX:+UseG1GC 

5、设置最大暂停时间:

-XX:MaxGCPauseMillis=50

6、设置并行线程数:

-XX:ParallelGCThreads=4

7、设置GC日志

-Xloggc:gc.log
打印GC日志:
-XX:+PringGCDetails 打印时间戳 -XX:+pringGCDateStamps
指定GC文件:
制定堆内存溢出时自动进行Dump
-XX:+HeadDumpOnOutOfMemoryError
-XX:HeadDumpPath=/usr/local

三、调优

堆:

调整堆的初始大小和最大大小 (-Xms 和 -Xmx):
根据应用程序的内存需求,可以逐步增加 -Xmx 值,避免频繁的垃圾回收。
1、当内存不足时,出现outofmemoryerror
2、频繁地垃圾回收;可通过查看gc日志  -Xloggc:gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps

调整元空间的大小

1、应用加载大量类(例如,大型框架或库,动态代理,反射,JVM动态加载等)
2、频繁的类加载和卸载(会导致元空间的碎片化或元空间不断增长)

适当调整栈大小

1、出现 StackOverflowError 错误 增大
2、大量线程并发运行
过大的栈空间可能会导致内存浪费

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值