震惊! GC原来是这个样子.

时间:2022-07-25
本文章向大家介绍震惊! GC原来是这个样子.,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
刚学java的时候,你可能好奇,java的GC是个啥呢?

GC全称Garbage Collection/Collector(垃圾回收器),是一种虚拟机帮助程序员管理内存的方式.

打个比方.

你在C++程序员食堂吃饭,吃完了你得把盘子这些收拾干净然后送到指定地点.

但是呢,有时候你会忘掉收拾(吃完就溜~~),这个位置不就没人会坐了嘛,这就是忘记释放内存.


但是java程序员食堂就不一样了,(手动狗头),吃完了可以甩手就走.

因为有专门的阿姨帮他们收拾桌子.懒人的福利~~

垃圾收集算法

标记 - 清除算法

"标记 - 清除" 算法是最基础的算法.

首先,它会标记需要回收的对象,标记完成之后回收所有被标记的对象.

再次回到java食堂~~

举个栗子,今天梁非凡,老八,乌鸦喊你吃饭了,点了慢慢一大桌菜!饭店上菜嘛,有快有慢,吃完的盘子得撤掉来给下道菜留个空间.但是呢,不幸的是,盘子有大有小,之前小盘子的位置咋放大盘子?这可咋整呢?

复制算法

复制算法讲内存分成两个部分,而且每次只用一半,如果那一半快用完了,就把存活对象依序复制到另一块上,再把用过的那块全部清理掉.这种算法可以忽略内存碎片的问题,但是缺点也很明显,每次只能用一半的内存.

回到食堂上~~~

梁非凡大怒,把老板喊过来,训了一通.所以老板想了个法子,他把整张分成两块,每次只让阿姨在一块上菜,等上菜发现地方不够了,就移到另外一半上,这样就能有空间给大盘子了.

图片来自<<深入理解java虚拟机>>

但是呢,还是有个小问题,原本吃饭讲究排场,现在一张桌子只能用一半,多穷酸?

乌鸦看看老板说:"我说就别吃了",刚想掀桌子,你看了看架势不对头,赶紧劝老板再想个办法.

标记 - 整理算法

标记整理算法是让所有的存活对象都向一端移动,接着清理掉末端的所有内存

图片来着<<深入理解java虚拟机>>

.这样存活的对象就会聚集在一起,剩下的内存就可以直接清理了.

这次老板让阿姨先看哪些菜吃完了,然后把菜往同一个地方挪,这样位置不就大了嘛.

这个方法让乌鸦哥满意了,也就不掀他桌子了.

GC的发展过程

Serial 收集器

他是历史最悠久的收集器。而且光看名字就可以知道,这个收集器是单线程的(Serial:串行的)。

这意味着只有一个线程清理,不仅如此,用户线程在清理时必须终止(防止在清理过程中还会产生垃圾)

这个是Serial收集器的“Stop The World”

ParNew/Parallel Scavenge 收集器

ParNew/Parallel Scavenge 收集器是两个多线程的收集器.

不同的是,ParNew能配合CMS收集器使用.

CMS 收集器

CMS收集器基于"标记 - 清除" 算法,牺牲了吞吐量来换取垃圾回收速度.

它的运作过程分为四个步骤:

  • 初始标记
    • 仍会"stop the world",但是速度很快,因为只是简单标记GC Root可达的对象(存活的对象). 相当于你们在吃饭的时候阿姨喊你们停一下,看了看哪些菜没吃完.然后让你们继续吃.
  • 并发标记
    • 从"初始标记"阶段标记的对象开始找出所有存活的对象. 因为是并发执行的,所以会存在新生代变成老年代,或者老年代的对象引用发生改变的情况,这些再后面都是要重新标记的.
  • 重新标记
    • 会导致"stop the world",这个阶段需要标记整个老年代的存活对象.
  • 并发清除
    • 并发清除未被标记的对象. 但是因为线程还会运行,还会不断产生垃圾.而且这部分垃圾无法在这次清理时被清除, 只能等下次清理.称为"浮动垃圾".

G1收集器

G1收集器是垃圾回收技术里程碑式成果之一,设计的目的是在维持高吞吐量的同时还能缩短内存回收时的停顿时间.至JDK14为止,G1还是默认的GC策略

特点:

  • 使用Region部分取代分代的作用
  • 可以由用户指定期望的停顿时间

G1之前的收集器,都有明确的垃圾收集的范围(新生代,老年代 etc),而G1将堆分为很多歌固定大小的区域(Region),每一个区域都能根据需要扮演不同的角色(新生代空间,老年代空间,Eden空间).

而且G1还有一类特殊的类型,巨型区域(Humongous Region),用来存放哪些大对象,判断的依据是对象是否超过50%Region的存储空间.

G1的运作分为以下四个步骤:

  • 初始标记
    • STW(stop the world),标记处GC Root 直接可达的对象
  • 并发标记
    • 对对象进行可达性分析,耗时长
  • 最终标记
    • 标记在并发标记时留下的少量STAB记录.
  • 筛选回收
    • 按照Region回收价值和时间进行排序,根据用户指定的停顿时间进行回收工作,回收部分Region.

ZGC

设计目的:

  • 最大停顿时间少于10ms
  • 停顿时间不会随着堆大小的变化而变化
  • 支持8MB到16TB的堆

特点:

  • 并发的
    • 少数操作需要STW,大部分并发执行
  • 基于Region
    • 完全取消了分代的概念,使用Region/Page进行划分
  • 压缩
    • 解决了内存碎片化的问题
  • 支持 NUMA架构
  • 染色指针(标志性设计)
    • 之前如果要在对象中添加额外信息的话,需要在对象头中添加,但是ZGC选择在指针中添加额外信息,使得标记只与对象的引用有关.
  • 读屏障
    • 用于对象引用地址是否满足条件

技术创作101训练营