JVM垃圾回收机制

引用计数法

要了解JVM的垃圾回收机制,首先要了解一下其他系统的垃圾回收机制。
什么是引用计数法呢?
当我创建了一个对象,

Person p = new Person();

p就叫做Person对象的一个引用,
引用计数法的原理是,对象上有一个标记数字,用来记录对象被引用的次数,当一个对象被引用一次的时候,该标记数字会加一,当该对象的一个引用失效的时候,该标记数字会减一,如果该数字减为0,那么该对象会被回收。
这种计数法可以行的通,但每次都要去计数,内存会有一定的开销,
而且最大的问题是,当两个对象之间循环引用的时候,垃圾回收器无法对其进行回收

class Person{

    Person p;
    void test(){
         Person p1 = new Person();
         Person p2 = new Person();
         p1.p=p2;
         p2.p=p1;
         p1=null;
         p2=null;
    }
    
}

这种情况下,在p1,p2为null之前,其引用的对象的引用计数都是2,
当p1,p2都为null时,p1的计数会减一,若要满足垃圾回收的条件,需要回收p2的p这个引用,如果要回收p2的p这个引用,需要先回收p2所引用的对象Person(),但这个对象又被p1的p所引用,所以要去回收p1的p这个引用,但要回收p1的p,需要先回收p1所引用的对象Person(),但这个对象又被p2的p所引用,如此的循环往复,导致这两个对象无法被回收。这就是引用计数法的弊端。

JVM自适应回收机制

聊完了自适应回收机制,
我们来聊一聊JVM的先进的自适应回收机制
为什么称为自适应回收机制呢?因为它有两种模式,可以根据不同的情况改变回收的机制。

标记——清扫

第一种叫标记——清扫,当JVM内存heap中的对象创建不是很频繁、资源的使用不大的时候,这种情况下,heap中会有两块区域,新生代y与老年代o,垃圾回收器会不定时的去heap和method area去检查,将y中“活”的对象都找出来,并标记上,当全部标记完成的时候,会进行下一个步骤:清扫,将不被标记的对象释放内存资源。这种模式的优点是占用内存小,缺点是y中清除对象后会存在碎片。

暂停——复制

当heap中的对象创建与失效比较频繁、内存占用比较大的时候,gc会切换至第二种模式:stop-copy,也就是暂停复制,这时候,heap新生代区域y会划出两块区域s0与s1,gc在对内存回收的时候,会先暂停程序的执行,并找出y中“活“的对象,将这些对象拷贝,复制到s0,然后将y清空,当第二次再次回收的时候,gc会将s0和y中的“活”对象都找出来,并拷贝至s1,然后清空y与s0,下一次再来的时候,就是拷贝至s0,并清空s1与y,如此反复。这种模式的缺点是占用的内存较大,且程序要暂停运行,优点是可以清理内存碎片,使内存合理的使用。

自适应是如何解决循环引用的问题

在说明这个问题之前,我们需要先了解一下JVM中的内存分配,
JVM中一共分成了五块区域,分别是:
1.线程私有区
(1).程序计数器
用来存储虚拟机栈中方法执行的顺序
(2)虚拟机栈
用来对线程执行的方法进行压栈与出栈,保证方法的有序进行
(3)本地方法栈
用来存储非java语言调用的方法
2.线程共享区
(1)heap:堆
用来存储对象和数组
(2)metaSpace:方法区
用来存储静态变量、常量、常量池、类信息

在这里插入图片描述

jvm的垃圾回收算法是可达性算法:
从gc root为起点开始搜索,heap中可以到达的对象就是活的对象,不能到达的对象就是垃圾对象。
gc root:虚拟机栈、本地方法栈、方法区中的引用都可以成为gc root
还是用之前的例子讲解

class Person{
    Person p;
    void test(){
         Person p1 = new Person();
         Person p2 = new Person();
         p1.p=p2;
         p2.p=p1;
         p1=null;
         p2=null;
    }
}

当p1、p2都未置为null的时候,gc在虚拟机栈中找到两个gc root p1、p2,并且能够去堆中找到它们指向的对象Person()实例1与实例2,认为这两个对象都是“可达”的,当p1、p2都置为null时,gc没有找到p1、p2所指向的对象,所以认为堆中的两个对象都是垃圾对象,会找机会清理。由此便解决了对象的相互循环引用问题。
在这里插入图片描述
怎么样,到这里你get到了吗?给我点个赞哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值