魔都才开始垃圾分类,有些人还是傻傻分不清垃圾应该怎么分类,Java真是伟大的语言(傲娇脸)早就实现垃圾分类回收了! 还不懂就out了!
什么?你说现实里的垃圾分类有图文说明,看看就明白?Java里的垃圾回收是算法写的,看不懂? 拜托!要是看看就明白,怎么还会流传“猪能吃的是湿垃圾,猪不吃的是有害垃圾……”
但是Java世界的回收划分很简单,只分可回收还是不可回收~
所以计算机的世界其实更简单。
虽然Java开发同学不用像C和C++的同学,自己申请了内存,要惦记着不用的时候释放掉,申请了就不管了,但是不用关心不代表它不重要,有些看不见的不代表不会影响你。
马路上很常见的垃圾桶分为:干垃圾和可回收垃圾,像纸箱、金属、塑料瓶,都是属于可回收的。
在0-1的世界里,所谓“垃圾回收”,就是指收回那些不可能再被任何途径使用的对象所占的内存空间,释放了这些内存可以给需要的对象使用。
那么JVM里是怎么来分的?或者说哪些对象是需要被回收的?
主要有两种算法来判断:引用计数法和可达性分析法。
算法 | 思想 | 优点 | 缺点 |
---|---|---|---|
引用计数法 | 给对象中添加一个引用计数器,每当一个地方引用这个对象时,计数器值+1;当引用失效时,计数器值-1。 | 判定效率很高 | 很难解决对象之间相互引用的情况; 开销较大、频繁且大量的引用变化,带来大量的额外运算 |
可达性分析法 | 通过一系列称为“GC Roots”的对象作为起始点,从这些节点向下搜索,当GC Roots到某个对象不可达时,这个对象就是可回收的。 | 更加精确和严谨,可以分析出循环数据结构相互引用的情况 | 实现比较复杂;需要分析大量数据,消耗大量时间 |
引用计数法,最大的问题是很难解决对象之间互相引用的情况。
这是两个对象互相引用的情况,除此之外,这两个对象再无引用,但因为它们的引用计数不为0,所以引用计数器无法通知GC收集器回收它们。
这是循环引用的情况,没有外部引用指向它们,但它们的引用计数不为0,就无法进行回收了。
所以主流的jvm都不使用引用计数法来管理内存,而是采用下面的可达性分析法,下图是它的基本思路示意图。
由图可知,object5、object6和object7都没有到GCRoots对象的引用链,它们都会被回收。
可以做为GC Roots的包含以下几种: