为啥要垃圾回收
为啥要垃圾回收,因为内存是有限的,我们从磁盘读取了需要使用的数据到内存,过了一段时间之后,该数据就不需要使用了。我们需要清理内存,给之后需要的程序使用。
如何判断一个数据是有用还是没有用的
通常有两种办法:
1、引用计数法(如果被引用那么就在对象头那边计数加一),但是这种办法无法避免循环引用的问题。
2、可达性分析
相当于好多个起点,从这些起点开始,联通的点,都需要保留着。就是,可以从这些点达到。
用并查集算法就可以做到。当然,实际不可能只是并查集这么简单。
可达性分析,首先得有根。
那哪些是根呢?
1、虚拟机栈中引用的对象。(比如被调用的方法堆栈中使用到的参数、局部变量、临时变量)
2、方法区中的类静态属性引用对象。
3、在方法区中,常量引用的对象。
4、在本地方法栈中Native方法引用的对象。
5、Java虚拟机的内部引用。(基本数据类型,异常对象,系统类加载器)
6、所有被同步锁持有的对象。
7、反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地缓存代码等
现在的垃圾回收器一般是局部性的收集,有时候需要其他对象临时加入一下下。
这里可以提一下黑白灰三色标记法。其实算是并查集的一种描述吧。
白色:尚未被垃圾收集器访问过。
黑色:已经被垃圾收集器访问过,该节点已经跟根节点建立了联系。
灰色:已经被垃圾收集器访问过,但是并没有跟根节点建立联系。以后的关系查询,可能可以证明它是跟根节点有联系的,也可能没有。最后才会知道。
为什么进行可达性分析的时候,需要使用,The world砸瓦鲁多替身。
因为可达性分析,就是分析当前对内存的占用,与根节点的关系。如果关系一直在变动,会导致两种情况。
把需要清除的垃圾,当成了可达的数据,这个也没什么,也就是清理不干净罢了。
如果把可达的数据,当成了要清除的垃圾,那这个问题就大了。
本来运行的好好的程序,找不到对应的对象了。那就炸了。
Wilson与1994年在理论上证明了,当且仅当以下两个条件同时满足时,本来是黑色的对象,才会被误认为是白色。
1、赋值器插入了一条或多条从黑色对象到白色对象的新引用。(增量更新)
2、赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。(原始快照)
增量更新:扫描结束后,重新扫描这个黑色对象为根开始的对象。(CMS)
原始快照:灰色对象删除白色对象的链接。扫描结束后,重新扫描这些灰色对象跟白色对象的链接。(G1,shenandoah)
这里只是简要的提及一下,之后我们将继续深入下去。