读了周志明的《深入理解java虚拟机》收获很大,这里总结一下对java垃圾回收机制的理解。
java堆是对象实例存放的主要地点,也是进行垃圾回收的主要区域。
那么,如何区分对象是否应该被回收?
可达性分析算法(还有一种引用计数法,但是会因为对象之间相互引用产生错误):以GC Roots的对象为根节点向下搜索,也就是说其中的对象节点不可到达,则说明这个对象没有存在的必要,但并不是直接销毁,现将其标记,关入大牢。
在java中,GC Roots的对象包括这几种:
虚拟机栈(栈帧中的本地变量表)中引用的对象。
方法区中类静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI引用的对象。(这个不懂)
这时候,对象并没有被杀死,只是被标为犯罪嫌疑人了,先关进大牢中(F-Queue 队列),需要配合调查。
标记对象需要通过覆盖finalize()方法配合调查,如果无罪(被标记的对象重新被引用,如Class.Object=this ),那么便成功逃脱了,但是机会只有一次(finalize()方法只会被调用一次)。
对象如何被回收,三种垃圾回收算法:
标记-清除(mark-sweep)算法 : 简单的说就是将被标记的对象清除。
复制(copying)算法 : 将整个空间一分为二,每次使用其中一个空间,将一个存活的对象复制到另一个空间中,再清理使用过的那个空间。
标记-整理(mark-compact)算法 : 标记过程与“mark-sweep”一样,之后让存活的对象移向同一端,在清理其外的内存区。
在jvm中,java堆划分为新生代(Young gen),和老年代(Old gen) 。(只是根据对象的存活周期划分)
新生代中又分为Eden,from survivor,to survivor三部分 ,Eden+from 是实例对象时刻伴随着大量产生和消亡。to中则存放在前者中存活下来的实例对象。
(博主水平太渣,写不下去了)