java虚拟机(三)java的垃圾回收机制详解

java中的垃圾回收算法是如何确认哪些对象是活的,哪些对象是死的?

对于判断对象是活是死,有两种不同的算法可以运用:

引用计数算法:

给对象中添加一个引用计数器,如果有一个地方引用他,计数值就加一,当引用失效后,计数值就减一。每次进行垃圾回收时,将那些引用计数器值为0的对象回收,这就是引用计数算法。但是java语言并没有选择这种算法,原因是当两个对象相互引用时,引用计数器的值永远不会等于0,而这里的对象如果不被使用就理应是垃圾。

objA.instance=objB; objB.instance=objA;

根搜索算法:

根搜索算法是主流的面向对象程序语言中用来判定对象是否存活的算法,也是目前主流java虚拟机所用到的垃圾回收算法。

基本思路:通过一系列名为"GC Roots"的对象作为起始点,从这些节点向下搜索,搜索的路径称为引用链,如果一个对象没有和任何引用链相连,就说明这个对象是没有用的,就是可以回收的对象。

可作为GC Root的对象:

1.虚拟机栈中引用的对象

2.方法区中的类静态属性引用的对象

3.方法区中的常量引用的对象

4.本地方法栈中JNI的引用的对象

关于引用:

从刚开始学java的时候,我的老师就告诉我java中到处都是引用,同样判断对象是否可以回收也和引用有关系。在java中有四种引用:

强引用(Strong):强引用是我们最常用到的,也是程序中最普遍存在的,如

Object obj=new Object();

软引用(soft):软引用是那些还有用,但非必要的对象。当系统的内存即将要溢出时,软引用的对象会被当成可以回收的对象。java中提供了SoftReference类实现软引用

弱引用(Weak):弱引用的强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集发生之前,当垃圾收集器工作时,无论当前内存是否足够,都会回收掉植被弱引用关联的对象。java中提供WeakReference类来实现弱引用

虚引用(Phantom):这个英文单词的意思是幽灵的意思,因此虚引用也被称为幽灵引用,它是最弱的一种引用。无法通过虚引用来取得一个对象实例,为一个对象设置虚引用关联的唯一目的就是当这个对象被回收时收到一个系统通知,java提供PhantomReference类来实现虚引用。

方法区的垃圾回收:

我们都知道java创建的对象都放在虚拟机的堆中,GC也主要发生在Heap中。对于方法区要不要进行垃圾回收也是一个问题,java虚拟机规范中说可以不要求虚拟机在方法区实现垃圾回收,因为在方法区进行垃圾回收性价比很低。在堆中,尤其是在新生代中,一次垃圾回收可以回收70%-95%的空间,但是在方法区中效率很低。

方法区需要回收的主要是废弃常量和无用的类,以常量为例,当一个字符串常量已经进入常量池,且没有任何对象引用这个常量,这个时候,可以对这个常量进行回收。

虽然java虚拟机规范中说明可以不回收方法区的垃圾,但是在大量使用反射、动态代理,CGLib等场景,以及动态生成JSP等频繁自定义ClassLoader等场景都需要虚拟机对方法区进行回收,以防止永生代的溢出。

垃圾收集算法:

不同的虚拟机所采用的垃圾收集算法各不相同,介绍几种常用的垃圾收集算法实现原理:

标记-清除算法:

最基础的收集算法,分为标记和清除两个阶段,首先标记处需要回收的对象,在某个时间点统一收集被标记的对象,但是缺点也很明显,标记和清除过程的效率都不高;标记清除后会产生大量不连续的内存碎片。

复制算法:

复制算法将内存按容量分为大小相同的两块,每次只使用其中一块,当这一块的内存用完之后,就将还存活的对象复制到另外一块上,把已经使用的内存空间一次性处理掉。这样就不需要考虑内存碎片的问题。缺点是可用内存变成了原来的一半,代价十分高。

但其实内存的划分不需要按照1:1来分,新生代中的对象有98%是会被回收的,现在的虚拟机很多都是采用这种算法实现垃圾收集。将新生代的内存分为一块Eden空间和两块Survivor空间,比例为8:1:1,当一个对象刚创建时,会进入Eden空间,一次GC还存活的对象会进入Survivor,每存活一次岁数就加1,等加到一定岁数这个对象就会进入老年代。因为新生代对象的回收率很高,所以每次把Eden和其中一块Survivor中存活的对象放到另一块对象中,再把清理这两块内存中的对象,这样浪费的空间只占10%,远远小于刚才的50%。因为不能保证存活的对象总小于10%,所以还需要老年代的内存进行分配担保,当存活对象大于10%时,需要借用老年代的内存。

标记-整理算法:

这个算法的过程和标记-清除算法类似,只不过在标记完之后不是立刻清除,而是把存活的对象都往一侧移动,然后再清除掉边界之外的对象

发布了54 篇原创文章 · 获赞 604 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41973594/article/details/102992786