转载

来自JVM的灵魂拷问:你是什么垃圾?

魔都才开始垃圾分类,有些人还是傻傻分不清垃圾应该怎么分类,Java真是伟大的语言(傲娇脸)早就实现垃圾分类回收了! 还不懂就out了!

什么?你说现实里的垃圾分类有图文说明,看看就明白?Java里的垃圾回收是算法写的,看不懂? 拜托!要是看看就明白,怎么还会流传“猪能吃的是湿垃圾,猪不吃的是有害垃圾……”

但是Java世界的回收划分很简单,只分可回收还是不可回收~

所以计算机的世界其实更简单。

Java开发需要熟悉GC吗?

虽然Java开发同学不用像C和C++的同学,自己申请了内存,要惦记着不用的时候释放掉,申请了就不管了,但是不用关心不代表它不重要,有些看不见的不代表不会影响你。

回收哪些对象 —— To be or not to be

马路上很常见的垃圾桶分为:干垃圾和可回收垃圾,像纸箱、金属、塑料瓶,都是属于可回收的。

在0-1的世界里,所谓“垃圾回收”,就是指收回那些不可能再被任何途径使用的对象所占的内存空间,释放了这些内存可以给需要的对象使用。

那么JVM里是怎么来分的?或者说哪些对象是需要被回收的?

哪些对象可回收?

主要有两种算法来判断:引用计数法和可达性分析法。

算法 思想 优点 缺点
引用计数法 给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。 判定效率很高 很难解决对象之间相互引用的情况; 开销较大、频繁且大量的引用变化,带来大量的额外运算
可达性分析法 通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,当GC Roots到某个对象不可达时,这个对象就是可回收的。 更加精确和严谨,可以分析出循环数据结构相互引用的情况 实现比较复杂;需要分析大量数据,消耗大量时间

引用计数法,最大的问题是很难解决对象之间互相引用的情况。

来自JVM的灵魂拷问:你是什么垃圾?

这是两个对象互相引用的情况,除此之外,这两个对象再无引用,但因为它们的引用计数不为0,所以引用计数器无法通知GC收集器回收它们。

来自JVM的灵魂拷问:你是什么垃圾?

这是循环引用的情况,没有外部引用指向它们,但它们的引用计数不为0,就无法进行回收了。

所以主流的jvm都不使用引用计数法来管理内存,而是采用下面的可达性分析法,下图是它的基本思路示意图。

来自JVM的灵魂拷问:你是什么垃圾?

由图可知,object5、object6和object7都没有到GCRoots对象的引用链,它们都会被回收。

可以做为GC Roots的包含以下几种:

来自JVM的灵魂拷问:你是什么垃圾?
原文  https://juejin.im/post/5d25aa94f265da1b8f1aea57
正文到此结束
Loading...