在Java,可作为GCRoots的对象包括:
1.方法区:类静态属性引用的对象;
2.方法区:常量引用的对象;
3.虚拟机栈(本地变量表)中引用的对象.
4.本地方法栈JNI(Native方法)中引用的对象。
注:即使在可达性分析算法中不可达的对象,VM也并不是马上对其回收,因为要真正宣告一个对象死亡,
至少要经历两次标记过程:第一次是在可达性分析后发现没有与GCRoots相连接的引用链,第二次是
GC对在F-Queue执行队列中的对象进行的小规模标记(对象需要覆盖 finalize() 方法且没被调用过).
III.GC原理-垃圾收集算法
分代收集算法VS分区收集算法
分代收集
当前主流VM垃圾收集都采用”分代收集”(GenerationalCollection)算法,这种算法会根据对象存活周
期的不同将内存划分为几块,如JVM中的新生代、老年代、永久代.这样就可以根据各年代特点分别采
用最适当的GC算法:
在新生代:每次垃圾收集都能发现大批对象已死,只有少量存活.因此选用复制算法,
只
需
要
付出
少
量
存
活
对
象
的
复
制
成
本
就
可
以
完成
收
集
.
在老年代:因为对象存活率高、没有额外空间对它进行分配担保,就必须采用“标记—清
理”或“标记—整理”算法来进行回收,
不
必
进行
内
存
复
制
,
且
直
接
腾
出
空
闲
内
存
.
分区收集
上面介绍的分代收集算法是将对象的生命周期按长短划分为两个部分,而分区算法则将整个堆空间划分
为连续的不同小区间,每个小区间独立使用,独立回收.这样做的好处是可以控制一次回收多少个小区间.
在相同条件下,堆空间越大,一次GC耗时就越长,从而产生的停顿也越长.为了更好地控制GC产生的停顿
时间,将一块大的内存区域分割为多个小块,根据目标停顿时间,每次合理地回收若干个小区间(而不是整
个堆),从而减少一次GC所产生的停顿.
分代收集
新生代-复制算法
该算法的核心是将可用内存按容量划分为大小相等的两块,每次只用其中一块,当这一块的内存用完,就将还存
活的对象复制到另外一块上面,然后把已使用过的内存空间一次清理掉.
评论0
最新资源