jvm的垃圾回收器怎么判断垃圾
JAVA的垃圾回收器有两种判断方式,一种是老版的回收算法,而另一种正式我们最常用JAVA1.8版本所正在使用的垃圾回收算法:
1.引用计数法(老版JDK判定垃圾的算法,有缺陷)
2.根搜索算法
两种算法明细:
引用计数法(概念和缺陷):
每当对象被引用时,引用系数加一。当一个引用被去除时,引用系数减一,当引用 系数为零时,当前对象会被判断为垃圾。
问题?
当一个方法运行完毕,但是方法中有两个对象相互引用,这两个对象会被判定为垃圾进行回收吗?
答案是不会,这就是为什么引用计数法被淘汰的原因。当相互引用的对象不能回收,所占据的内存不能被释放,而在程序运行期间这样的对象逐渐变多时,占据的内存也会越来越多。从而导致内存泄漏问题,这是不可修复的错误。你能想到上线的项目动不动就因为内存泄漏而崩溃的场面吗?互联网行业是公认的用户满意度要求较高的一个行业之一,每一次项目崩溃,都会导致大量的用户流失,这是任何企业都不容忽视的损失。
根搜索算法(别名:可达性搜索算法)
根搜索算法,是取代了的引用计数法的一种回收算法,它没有引用计数法的缺陷。
它判断垃圾的方式是追溯对象的引用链,找到对象的引用存根。当有根时,当前对象不是垃圾。当无根时,当前对象就是垃圾。
根是什么?
引用链的最上端,当应用链的最上端是在栈或方法区时,这就是根。
怎么解决的相互引用问题?
相信很多人不理解根搜索算法怎么解决的相互引用问题,因为根搜索算法必须要有根在方法区和栈的空间中。而相互引用的对象则因为对象是存在于堆内存中,即使相互引用,追溯引用链,也只能追溯到堆内存中,到不了栈和方法区。所以即使对象相互引用也会被判断为垃圾,因为它们没有根。