全面学习JVM内存管理及GC机制(二)

本文深入探讨了JVM的垃圾回收(GC)机制,解释了为何采用分代回收,详细阐述了虚拟机中的GC过程,包括Minor GC和Major GC。同时,介绍了几种垃圾收集器,如串行收集器、并行收集器、CMS收集器和G1收集器,以及它们各自的特点和适用场景。
摘要由CSDN通过智能技术生成

一.虚拟机中的GC过程

1.1为什么要分代回收?

在一开始的时候,JVM的GC采用的就是标记-清除-压缩的算法进行回收内存,但是当分配的对象很多,对象的列表变大,扫描和移动的时间很长,反而内存回收会特别慢。然而,经过对java应用的分析,发现大部分对象的存活时间较短,下面的图可以看出java对象在内存中存活时间的统计:
在这里插入图片描述从上表中可以看出,存活时间长的对象只占一小部分,所以对堆中采取分代管理内存和分代回收内存的机制,年轻代由于对象存活时间较短,可以采用复制的GC算法来快速回收内存,而对于老年代中存活时间较长的对象,就可以采用标记-清除-压缩的算法来实现高效的内存回收。

1.2虚拟机中GC过程

上面我们解释了虚拟机为何要采用分代回收,下面让我们理清以下虚拟机中的整个GC过程。
1.在初始阶段,新创建的对象在Eden区,Survivor的两块都为空。
在这里插入图片描述
2.当Eden区满了的时候,Minor GC被触发
在这里插入图片描述
3.经过扫描与标记,存活的对象被复制到空的S0区域,不存活的对象被回收
在这里插入图片描述
4.在下一次的Minor GC中,Eden区和之前一样,存活的对象被复制到Survivor区,未存活的对象被回收,不过这一次不同的是,Eden区中存活的对象被复制到了S1区,而S0区中未存活的对象被回收,存活的对象被移动到了S1区,S0被清空,但是这里之前在S0中存活的对象在移动到S1中后,年龄要加1,所以此时S1中存活了不同年龄的对象。
在这里插入图片描述
5.再一次Minor GC,此时S0和S1区对换,所有存活的对象被移动到S0区,S1区和Eden区对象被清空。
在这里插入图片描述
6.下面演示一下Promotion过程,经过几次Minor GC过程后,当年轻代中存活的对象年龄达到一个值时,(可以进行参数设置,默认为8),就会被从年轻代Promotion到老年代。
在这里插入图片描述
7.随着一次一次的Minor GC,会有对象在达到年龄后被送到老年代
在这里插入图片描述
8.上面就是整个年代的回收过程,最终,Minor GC将会在老年代发生,老年代的空间将会被标记清除压缩。
在这里插入图片描述
从上面的过程我们可以看出,在年轻代的Eden区和Survivor区,Eden区的分配是连续,并且总有一个Survivor区是空的,经过一次GC和复制,Eden区和一个Survivor区中的存乎对象被子复制到了另一个Survivor区,并且他们中的对象都被清空了,在下一次GC时,两个Survivor区再交换角色,重复上述过程,这种垃圾回收方式就是著名的停止-复制清理法。这种分配清理垃圾的方法特写快速和高效,但是在老年区,由于存活对象时间较长,使用这种算法效率就不高了。

对于老年代,一般使用的是标记-压缩算法,存活对象标记,清除未存活对象,并将对象向一端移动,使内存连续。在发生Minor GC的时候,虚拟机每次会检查晋升进入老年代的大小是否超出老年代剩余的空间,如果超出,就直接进行一次Full GC,如果小于老年代剩余的空间,就看是否设置了-XX:+HandlePromotionFailure(允许担保失败),这个参数如果设置了的话,就会在进行一次MinorGC时,就进行一次FullGC,不管老年代还有多少内存,这样做不好,建议不要设置。

对于方法区即持久代的内存回收,主要回收两种:常量池中的常量,无用的类信息。常量的回收很简单,没有被引用了就回收,对于类的信息的回收,要满足以下三点:

  1. 类的所有实例都已经被回收
  2. 加载类的ClassLoader已经被回收
  3. 类对象的Class对象没有被引用(即没有通过反射引用该类的地方)

永久代的回收不一定是必须的,可以通过参数进行设着。

二.垃圾收集器

前面我们已经了解了JVM内存回收的过程,在虚拟机中,GC是通过垃圾收集器实现的,在不同的应用场景要选择不同的垃圾收集器,下面让我们来介绍一下垃圾收集器。

2.1串行收集器(Serial)

串行收集器是在JavaSE5和6中客户端虚拟机中的默认设置,是最简单的收集器,适合单个处理器的系统。在串行收集器中 Minor和Major GC都是通过一个线程进行垃圾回收
使用场景

  • 对应用暂停要求不是很高和运行在客户端模式的场景。它仅仅使用一个cpu核心进行垃圾回收。
  • 一台机器中运行多个JVM虚拟机的时候,使用串行收集器,一个JVM只需要一个处理器,对其他虚拟机没有影响。
  • 内存比较小,cpu核心数比较少的硬件设备上使用

相关命令参数
启用串行收集器: -XX:+UseSerialGC
命令行示例:java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -XX:+UseSerialGC -jar c:\javademos\demo\jfc\Java2D\Java2demo.jar

2.2并行收集器

并行收集器使用多线程的方式进行垃圾回收,能带来极大的cpu吞吐量,并行收集器是Server级别的机器(cpu大于2,内存大于2G)时的默认回收方式
应用场景
并行回收器适用于多CPU、对暂停时间要求短的情况下。通常,一些批处理的应用如报告打印、数据库查询可采用并行收集器。

2.3CMS收集器

CMS收集器用于永久区的垃圾回收,试图用多线程的方式来减少垃圾回收过程的暂停,不会对对象进行复制和移动。
使用场景
CMS收集器主要用在应用程序对暂停时间要求很高的场景,比如桌面UI应用需要及时响应用户操作事件、服务器必须能快速响应客户端请求或者数据库要快速响应查询请求等等。

2.4G1收集器

G1即Garbage First,它是在java 7中出现的新的收集器,它的目标是替换掉现有的CMS收集器。G1具有并行、并发、增量压缩、暂停时间短等特点,在这里先不做详细介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值