JVM_垃圾回收_GC

简述

垃圾回收

程序的运行必然需要申请内存资源,无效的对象资源如果不及时处理就会一直占有内存 资源,终将导致内存溢出,所以对内存资源的管理是非常重要。

为了让程序员更专注于代码的实现,而不用过多的考虑内存释放的问题,所以,在Java语 言中,有了自动的垃圾回收机制,也就是我们熟悉的GC。

垃圾回收算法

常见的垃圾回收算法有:引用计数法、标记清除法、标记压缩法、复制算法、分代算法 等。

引用计数法

假设有一个对象A,任何一个对象对A的引用,那么对象A的引用计数器+1,当引用失败 时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了, 可以被回收。

缺点:
每次对象被引用时,都需要去更新计数器,有一点时间开销。
无法解决循环引用问题。

标记清除法

标记:从根节点开始标记引用的对象。
清除:未被标记引用的对象就是垃圾对象,可以被清理。

标记清除算法解决了引用计数算法中的循环引用的问题,没有从root节点引 用的对象都会被回收。

缺点:
效率较低,标记和清除两个动作都需要遍历所有的对象,并且在GC时,需要停止应 用程序,对于交互性要求比较高的应用而言这个体验是非常差的。
通过标记清除算法清理出来的内存,碎片化较为严重,因为被回收的对象可能存在于 内存的各个角落,所以清理出来的内存是不连贯的。

标记压缩算法

标记压缩算法是在标记清除算法的基础之上,做了优化改进的算法。和标记清除算法一 样,也是从根节点开始,对对象的引用进行标记,在清理阶段,并不是简单的清理未标 记的对象,而是将存活的对象压缩到内存的一端,然后清理边界以外的垃圾,从而解决 了碎片化的问题。

缺点:
标记压缩算法多 了一步,对象移动内存位置的步骤,其效率也有有一定的影响。

复制算法

将原有的内存空间一分为二,每次只用其中的一块,在垃圾回收时,将正在使用的对象复制到另一个内存空间中,然后将该内存空间清空,交换两个内存的角色,完成垃圾的回收。

缺点:
在垃圾对象少的情况下,不适用,如:老年代内存 。
分配的2块内存空间,在同一个时刻,只能使用一半,内存使用率较低 。

分代算法

根据回收对象的特点进行选择,在JVM中,年轻代适合使用复 制算法,老年代适合使用标记清除或标记压缩算法。

垃圾收集器

算法的具体实现:串行垃圾收集器、并行垃圾收集器、CMS(并发)垃圾收集器、G1垃圾收集器。

搭配图:
在这里插入图片描述
图中展示了7种不同分代的收集器:

Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1;

新生代收集器:Serial、ParNew、Parallel Scavenge;
老年代收集器:Serial Old、Parallel Old、CMS;
整堆收集器:G1;

打印垃圾回收的详细信息

-XX:+PrintGCDetails

串行垃圾收集器

串行垃圾收集器,是指使用单线程进行垃圾回收,垃圾回收时,只有一个线程在工作, 并且java应用中的所有线程都要暂停,等待垃圾回收的完成。

对于交互性较强的应用而言,这种垃圾收集器是不能够接受的。
一般在Javaweb应用中是不会采用该收集器的。

设置方式:

-XX:+UseSerialGC    #指定年轻代和老年代都使用串行垃圾收集器 

并行垃圾收集器

并行垃圾收集器在收集的过程中也会暂停应用程序,这个和串行垃圾回收器是 一样的,只是并行执行,速度更快些,暂停的时间更短一些。

Parallel收集器也称吞吐量收集器,相比Serial收集器,Parallel最主要的优势在于使用多线程去完成垃圾清理工作,这样可以充分利用多核的特性,大幅降低gc时间。

设置方式:

‐XX:+UseParallelGC ‐XX:+UseParallelOldGC

CMS(并发)垃圾收集器

CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器, 该回收器是针对老年代垃圾回收的。

设置方式:

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC

G1垃圾收集器

JDK1.7以后,G1收集器(或者垃圾优先收集器)的设计初衷是为了尽量缩短处理超大堆(大于4GB)时产生的停顿。G1具备压缩功能,相对于CMS的优势而言是内存碎片的产生率大大降低。

G1中提供了三种模式垃圾回收模式,Young GC、Mixed GC 和 Full GC,在不同的条件下被触发。

调优步骤:
开启G1垃圾收集器 ;设置堆的大内存 ;设置大的停顿时间

设置方式:

-XX:+UseG1GC   # 使用 G1 垃圾收集器
-XX:MaxGCPauseMillis  # 设置期望达到的大GC停顿时间指标(JVM会尽力实现,但不保证达到),默认 值是 200 毫秒。
‐Xmx256m   # 设置最大堆内存大小

GC日志导出和分析

设置方式:

‐XX:+PrintGCDetails XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐XX:+PrintHeapAtGC Xloggc:F://test//gc.log

在线可视化工具:GC Easy
网站:https://gceasy.io/

案例

设置并行垃圾回收器

#年轻代、老年代均使用并行收集器,初始堆内存64M,大堆内存512M

set JAVA_OPTS=-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms64m -Xmx512m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:D:\\gc.log

在这里插入图片描述
分析:
在报告中显示,在5次GC时,系统所消耗的时间大于用户时间,这反应出的服务器的性能存在瓶颈,调度CPU等资源所消耗的时间要长一些。

在这里插入图片描述
分析:
年轻代的gc的次数,次数稍有多,说明年轻代设置的大小不合适需要调整 。
FullGC的次数,说明堆内存的大小不合适,需要调整。

调整方式:

set JAVA_OPTS=-XX:+UseParallelGC -XX:+UseParallelOldGC -Xms128m -Xmx1024m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:D:\\gc.log

在这里插入图片描述

设置G1垃圾回收器

set JAVA_OPTS=:+UseG1GC ‐XX:MaxGCPauseMillis=100 -Xms128m -Xmx1024m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintHeapAtGC -Xloggc:D:\\gc.log
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值