JVM之GC(垃圾收集器)(第四篇)

本文详细介绍了JVM中的垃圾回收器,包括GC的基本概念、分类及常见收集器如Serial、ParNew、Parallel、CMS和G1的特点和工作原理。GC主要分为串行和并行,强调了并发、停顿时间和吞吐量等因素对性能的影响。CMS和G1作为并发收集器,力求缩短暂停时间,但CMS存在浮动垃圾和碎片问题,而G1通过Region概念提高了效率和预测性。
摘要由CSDN通过智能技术生成

3.1 概念

GC 垃圾回收器是 JVM 中自动内存管理机制的具体实现,在 HotSpot 虚拟机中 GC 的工作主要划分为两
大类,分别是内存动态分配和垃圾回收,在内存执行分配之前,GC 首先会对内存空间进行划分,考虑到 JVM
中存活对象的生命周期会具有两极化,应该采取不同的垃圾收集策略,分代收集可以实现这个目标,目前几
乎所有的GC 都是采用分代收集算法执行垃圾回收
一般来说当内存空间中的内存消耗到达一定阈值之后,GC 就会执行垃圾回收,而且回收算法必须非常准确,
一定不能造成内存中存活的对象被错误的回收掉,也不能造成已经死亡的对象没有及时回收,而且 GC 执行
内存回收的时候应该做到高效,不应该导致程序长时间的暂停,以及要避免产生内存碎片,不过 GC 回收垃
圾的时候不可避免的会产生碎片,因为被回收的对象空间不是连续的,这样一来会导致没有足够的空间分
配给大内存对象,不过可以通过压缩算法来消除碎片
可以通过以下六点来评估一个 GC 的性能

  1. 吞吐量:程序的运行时间(程序时间+回收时间)
  2. 垃圾回收开销: 吞吐量的补数,垃圾回收器所占时间与总时间的比例
  3. 暂停时间: 执行垃圾回收的时候,程序的工作线程被暂停的时间
  4. 收集频率: 相对于程序的执行,收集操作发生的频率
  5. 堆空间: Java 堆占用的空间大小
  6. 快速: 一个对象从创建到被回收所经历的时间

3.2 垃圾回收器分类

由于 JDK 的高速迭代,Java 到现在已经衍生了很多版本的 GC,比如 Serial/Serial Old 收集器,ParNew 收集器,Parallel/Parallel Old 收集器,CMS(Concurrent-Mark-Sweep) 收集器,以及从 JDK7U4版本开始的出现的G1(Garbage-First)收集器等
按照不同的划分角度,可以将 GC 分为 不同的类型
按照 线程数 划分 可以分为 串行垃圾回收器并行垃圾回收器

  1. 串行回收指的是同一段时间内只允许一件事情发生,当有多个 CPU 的时候也只能有一个 CPU 用于
    执行垃圾回收操作,并且在执行回收的时候,程序中的工作线程会被暂停,回收结束后才会恢复,这就是
    串行回收,一般情况下串行回收被用在 client 模式下,和串行回收相反,并行回收可以使用多个 CPU 来
    执行垃圾回收,因此提升了应用的吞吐量,不过并行回收仍然使用 STW和复制算法
    串行回收有两个特点:首先 它仅仅使用单个线程进行垃圾回收, 其次它是 独占式 的垃圾回收方式
  2. 年轻代串行回收器使用复制算法,实现相对简单,逻辑处理特别高效,而且没有额外的线程切换开销,
    在诸如单 CPU 或者较小的应用内存等硬件平台,它的性能可以超过并行回收器
    并行收集器是工作在新生代 垃圾回收器,它只是简单的将串行回收器多线程话,它的回收策略算法
    以及参数和串行一致,并行回收器也是独占式的回收器,在收集过程中,也会 STW,不过在并发能力强
    的 CPU 上面,它产生的停顿时间小于串行收集器,效率更高
    按照 工作模式 分可以划分为 并发式回收器 和 独占式回收器 ,并发式(注意不是并行)回收器与应用程序
    线程交替执行,以尽量减少应用程序的停顿时间,独占式垃圾回收器一旦运行就停止应用中的其他线程,直
    到回收结束
    按照 碎片处理 方式分可以分为 压缩式垃圾回收器 和 非压缩式垃圾回器 ,压缩式垃圾回收器会在回收完
    成后堆存货对象进行压缩整理,消除回收后的碎片,非压缩式的垃圾回收器不会进行此过程
    按照 工作内存区间 划分又可以分为 年轻代垃圾回收器 和 年老代垃圾回收器

3.3常见垃圾回收器

3.3.1 Serial 收集器
Serial收集器是JAVA虚拟机中最基本、历史最悠久的收集器,在JDK 1.3.1之前是JAVA虚拟机 新生代 收集的唯一选择。Serial收集器是一个串行垃圾收集器,但它的“单线程”的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是在它进行垃圾收集时,必须暂停其他所有的工作线程,直到它收集结束,通过 -XX:+UseSerialGC 指定使用 Sarial 收集器

Serial收集器到JDK1.7为止,它依然是JAVA虚拟机运行在Client模式下的 默认新生代收集器 。它也有着优于其他收集器的地方:简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。在用户的桌面应用场景中,分配给虚拟机管理的内存一般来说不会很大,收集几十兆甚至一两百兆的新生代(仅仅是新生代使用的内存,桌面应用基本上不会再大了),停顿时间完全可以控制在几十毫秒最多一百多毫秒以内,只要不是频繁发生,这点停顿是可以接受的。所以,Serial收集器对于运行在低硬件资源的应用来说是一个很好的选择

Seiral Old 收集器
除了年轻代之外,Seiral 还提供了用于执行年老代垃圾收集的 Seiral Old 收集器, Seiral Old 收集器同样也采
用了串行回收和 STW 机制,只不过回收算法为标记-压缩算法,在 JVM 受制于单个 CPU 核心的环境下,使用
Seiral 收集器和 Se

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值