0
点赞
收藏
分享

微信扫一扫

JVM虚拟机-垃圾回收


垃圾回收机制

  • ​​哪些对象需要回收?​​
  • ​​可回收对象的判定​​
  • ​​可达性分析​​
  • ​​引用计数法​​
  • ​​什么时候发生回收?​​
  • ​​Minor GC​​
  • ​​Full GC​​
  • ​​触发Full GC的原因有哪些?​​
  • ​​对象何时晋升老年代​​
  • ​​以什么方式回收?​​
  • ​​垃圾回收算法​​
  • ​​垃圾回收器​​
  • ​​CMS​​
  • ​​G1(Garbage-First )​​

哪些对象需要回收?

一个对象需不需要回收,首先看他有没有被其他对象引用,如果没有引用了,那么这个对象就会成为“垃圾”需要被回收。回收判定的方式有两种:可达性分析和引用计数法

可回收对象的判定

可达性分析

主要是找出GC Roots的引用链。如果不在引用链中,那么就是需要回收的对象。

JVM虚拟机-垃圾回收_老年代


GC Roots包括什么呢?

GC Roots相当于根对象,是会长时间保存下来的对象。

  1. 虚拟机栈中引用的对象(局部变量表中)
  2. 本地方法栈引用的对象(本地方法形成对象)
  3. 锁持有的对象
  4. 方法区常量引用的对象
  5. 静态变量引用的对象

4种引用类型
强引用:比如GCroot 以及new创建的对象,虚拟机不会回收强引用,宁愿抛出OOM
软引用:描述一些有用,但是非必须的对象。当内存满了以后会对这些对象进行回收
弱引用:每次GC 都会回收
虚引用:可以用作通知工作(一旦这个对象被回收,相应的用户线程会收到通知并对直接内存进行清理工作。)

引用计数法

通过判断对象的引用数量来决定是否回收。当一个对象被其他对象引用的时候,引用计数器就加1,当不在被其他对象引用的时候减一。但是引用计数法不能够解决对象之间相互循环引用的问题。可达性分析可以解决。

JVM虚拟机-垃圾回收_老年代_02

什么时候发生回收?

当JVM触发GC的时候会进行垃圾回收,垃圾回收主要发生在堆区,按照内存管理主要在两个位置:新生代和老年代

Minor GC

主要发生在新生代(eden:from:to =8:1:1),由于新生代存放的是“朝生夕死”的对象,Minor GC会比较频繁。

Full GC

主要发生在老年代,当old区的内存空间不足就会触发Full GC 进行垃圾回收。

触发Full GC的原因有哪些?

  1. 老年代内存空间不足
  2. 担保失败:新生代晋升到老年代会有一个担保机制(担保晋升的对象不超过老年代的可用内存),如果担保失败就会触发 Full GC
  3. System.gc()
  4. 元空间内存达到阈值
  5. 大对象导致老年代内存空间不足

对象何时晋升老年代

  1. 大对象会绕过新生代,直接在老年代分配。(-XX:PretenureSizeThreshold可以设置,超过这个值直接进入老年代)
  2. 长期存活的对象会进入老年代
  3. 动态对象年龄判断(年龄的累加对象之和大于Survivor内存空间的一半,超过该年龄的将会进入老年代)
  4. Survivor满了,通过担保机制进入老年代

以什么方式回收?

垃圾回收算法

复制算法:

发生在新生代。复制算法的思想是将内存分为两部分,每次只使用一部分,存活下来的会复制到另外一块上,然后将本部分清空。

对象只会在存在eden区和名为“From”的Survivor区, Survivor区“To”是空的。当出现Minor GC时候,就会将eden存活的复制到to区,而from区会根据其年龄来判断去向,如果超过阈值年龄(默认15岁)就会进入old区(老年代),没超过就会进入to区,然后from区就会被清空。from和to进行互换。保证to区一直是空闲的。

JVM虚拟机-垃圾回收_用户线程_03

标记清除算法:
复制算法的缺点是空间利用率不足。标记-清除分为两个部分:标记-清除。缺点是存在碎片
**标记整理算法:**会将存活的对象移动到一端,对不存活的对象进行处理。

垃圾回收器

CMS

全称是并发标记清除,使用的是标记清除算,其设计目的是减少停顿时间。

JVM虚拟机-垃圾回收_引用计数_04


因为gc线程和用户线程一起执行,可以有效减少停顿时间。

分为四个阶段:

初始标记:有STW停顿,标记GC roots

并发标记:标记可达对象,用户线程和GC线程一直执行

重新标记:有STW停顿,对并发标记过程中,导致记录发生变动,需要重新进行标记

并发清除:GC线程和用户线程一起工作。

CMS中由于GC线程和用户线程一起工作,所以在GC的时候,内存需要留有一些内存,防止在gc过程中,用户线程产生对象撑爆老年代。

**优点:**并发收集,低停顿时间(只有初始标记和重新标记才会STW)

**缺点:**标记删除会存在碎片

G1(Garbage-First )

G1弱化了分代的思想,更多的使用分区(Region),Region之间是复制算法,但实际整体上可看作是标记-整理算法。

G1将整个堆划分成一个个大小相等的块(每个块称为Region),每一块的内存是连续的。分代算法一样,G1 中每个块也会充当 Eden、Survivor、Old 三种角色,但是它们不是固定的,这使得内存使用更加地灵活。

JVM虚拟机-垃圾回收_老年代_05


执行垃圾收集时,和 CMS 一样,G1 收集线程和应用线程并发执行,标记结束后,G1 也就知道哪些区块基本上是垃圾,存活对象极少,G1 会先从这些区块下手,因为从这些区块能很快释放得到很大的可用空间,这也是为什么 G1 被取名为 Garbage-First 的原因。

G1 使用了停顿预测模型来满足用户指定的停顿时间目标,并基于目标来选择进行垃圾回收的区块数量。G1 采用增量回收的方式,每次回收一些区块,而不是整堆回收。

​​垃圾收集器介绍​​


举报

相关推荐

0 条评论