JVM垃圾回收算法:引用计数法

什么是JVM?俗称而言我们称之为Java虚拟机,从进程而言,它是一个独立运行的java程序:

a)启动。启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void main(String[] args)函数的class都可以作为JVM实例运行的起点。

b)运行。main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程。

c)消亡。当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以用Runtime类或System.exit()来退出。

什么是垃圾回收?

程序的运行必然需要申请内存资源,无效的对象如果不及时清理就会一直占用内存 ,最终导致内存溢出,所以对内存资源的管理就是垃圾回收。

什么是引用计数法?
原理:假设有一个对象A,只要有任何一个对象引用了A,那么对象A的引用计数器+1,当引用失败 时,对象A的引用计数器就-1,如果对象A的计数器的值为0,就说明对象A没有引用了, 可以被回收。

引用计数法的优缺点

优点:
1)实时性高,无需等到内存不够才开始回收,运行时根据对象的计数器判断是否为0,为0则可以直接回收。
2)在垃圾回收过程中,应用无需挂起。如果申请内存时,内存不足,则立刻报outofmember错误。
3)区域性,更新对象的计数器时,只是影响到该对象,不会扫描全部对象。

缺点:
1)每次对象被引用都需要去更新计数器,有一点时间开销。
2)浪费CPU资源,即使内存够用,仍然在运行时进行计数器的统计。
3)无法解决循环引用问题(最大缺点):可能造成循环引用无法回收的情况。

public class Test {
   public static void main(String[] args) {
       TestA testA = new TestA();
       TestB testB = new TestB();
       testA.b = testB;
       testB.a = testA;
       testA = null;
       testB = null;
   }
}

class TestA{
    public TestB b;
}
class TestB{
    public TestA a;
}

虽然a和b都为null,但是由于a和b存在循环引用,这样a和b永远都不会被回收。

发布了185 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_39309402/article/details/103867954
今日推荐