JVM垃圾回收机制

JVM垃圾回收机制

对象存活判定方法

引用计数法

String str1 = "test";
String str2 = "test";

只要一个对象还有实用价值,我们可以通过他的引用变量来进行操作

  • 每个对象都包含一个引用计数器,用于存放引用计数(被引用的次数)
  • 每当有一个地方引用此对象时,引用计数加一
  • 当引用失效时,引用计数减一
  • 当引用计数为零时,表示此对象不可能再被引用。

存在问题->两个对象相互引用,引用计数器的值始终为一。

可达性分析算法

采用类似树结构搜索机制

每个对象引用都有机会成为树的根节点(GC Roots),成为根节点的条件:

  • 位于虚拟机的栈帧中的本地变量表索引用到的对象
  • 类的静态成员变量所引用的对象
  • 方法区中,常量池里面引用的对象,比如之前的String对象
  • 被添加了锁的对象(synchronized)
  • 虚拟机内部需要用到的对象

一旦以及存在的根节点不满足存在的条件时,根节点与对象之间的连接将断开,如果对象存在对其它对象的引用,但是由于没有任何根节点的引用,所以此对象可被判定为不再使用。

最终判定

经历了可达性分析算法后基本可能判断哪些对象能够被回收,但是并不代表此对象一定会被回收,会在最终判定阶段进行挽留。

Object类中的finalize()方法就是最终判定方法,如果子类重写了此方法,那么子类对象在被判定为可回收时,会执行这个方法进行二次确认。如果在二次确认后对象不满足可回收条件,那么对象不会被回收。

只能执行一次,第二次执行的时候会跳过,直接回收。

垃圾回收算法

分代收集机制

Java虚拟机将堆内存划分为新生代老年代永久代

image-20230306165311823

新创建的对象会放入Eden区,进行一次扫描,引用为空的对象会丢掉,剩下存活的对象转移到Survivor区,一开始From和To区都是空的,所有Eden存活的对象进入From区,最后From和To进行一次交换。

下一次垃圾回收,操作与上次一样,但是From区中有对象了,因此Eden区中的对象复制到From区后,会对To区的对象进行判定(每经历一次垃圾回收,年龄+1,对象年龄大于15,会直接进入老年代,否则会移入From区)

垃圾收集分为:

  • Minor GC - 次要垃圾回收,主要进行新生代区域垃圾收集
    • 触发条件:新生代Eden区容量满
  • Major GC:主要垃圾回收,主要对老年代垃圾收集
  • Full GC:完全垃圾回收,对整个Java堆内存和方法区进行垃圾回收。
    • 触发条件:
      • 每次晋升到老年代的对象平均大小大于老年代剩余空间
      • Minor GC后存活的对象超过了老年代剩余空间
      • 永久代空间不足(JDK8之前)
      • 手动调用System.gc()方法

空间分配担保

标记-清除算法

标记所有需要回收的对象,然后再依次回收被标记的对象,或者是标记所有不需要回收的对象,回收没有被标记的对象。

缺点:如果存在大量对象,就会存在大量标记,大规模清除后连续的内存空间可能会出现许多空袭,碎片化导致连续内存空间利用率降低。

标记-复制算法

将容量分为大小相同的两块区域,每次清除垃圾后将存活的对象全部复制到另一个区域,解决了碎片化问题。适用于新生代

标记-整理算法

标记对象后,将所有待回收的对象整齐排列,将后续对象全部清除。

垃圾收集器实现

Serial收集器

单线程,会终止当前用户线程,收集完后继续线程

Parallel Scavenge/Parallel Old收集器

JDK8使用这种组合方式垃圾回收方案

CMS收集器

Garbage First(G1)收集器

元空间

JDK8时直接将本地内存作为元空间(Metaspace)的区域,物理内存有多大,元空间内存就可以有多大

image-20230306165703340

其他引用类型

强引用:Object o = new Object(),JVM不会随意回收强引用对象

软引用

内存空间不足时,软引用指向对象会被回收,get()方法得到null,并且软引用对象本身被丢进队列中

弱引用

o = new Object()`,JVM不会随意回收强引用对象

软引用

内存空间不足时,软引用指向对象会被回收,get()方法得到null,并且软引用对象本身被丢进队列中

弱引用

进行垃圾回收时,不管内存空间是否充足,都会回收

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值