《深入理解java虚拟机》笔记
1.垃圾回收作用区域
程序计数器、虚拟机栈、本地方栈为线程私有,其内存在编译期可以确定,随线程结束或方法结束而回收。
Java堆、方法区由于只有在运行期才能知道需要创建哪些对象,有很大的不确定性,所以内存由垃圾收集器(GC)回收。
2.对象存活判定算法
2.1 引用计数法
概述:给对象添加一个计数器,被引用则+1,引用失效则-1,为零时则被回收
优点:判断效率高
缺点:1)额外花销内存来技术
2)如果对象之间互相引用则无法回收
2.2 可达性分析
概述:把一些重要的对象列为GC Roots(根对象),如果其他对象通过引用链最终能达到GC Roots,则说明对象还有用,不回收,反之则考虑回收。
该算法被Java虚拟机所使用。
3.分代收集理论
-
弱分代假说:绝代多数对象都是朝生夕灭的。
-
强分代假说:熬过越多次垃圾收集的对象就越难以消亡。
-
跨代引用假说:跨代引用相对于同代引用来说仅占极少数。
根据这三条假说,JVM设计者将Java堆划分为新生代和老年代两大区域。对于少量的跨代引用,不必再遍历整个老年代来进行可达性分析,只需要在新生代上建立一个数据结构(称为“记忆集”),将老年代划分为若干小块,标记出哪些内存存在跨代引用。
4.垃圾收集算法
- 标记-清除算法
概述:首先标记出所有需要回收的对象,然后统一回收。
缺点:
1)如果大部分对象需要回收,效率较低。
2)会造成内存空间泄露的问题。 - 标记-复制算法
概述:将内存划分为两块,每次只使用其中一块,当一块内存用完了就将还存活的对象复制到另外一块上面,再将已使用过的内存一次性清理掉。
缺点:
1)如果对象存活率较高,就要进行较多次的复制操作,效率较低(不适用于老年代)。
2)会浪费一部分内存。
“Appel式回收”策略:将新生代分为一块Eden和两块Survivor区域,他们的大小比例为8:1:1,每次内存分配只使用Eden和一块Survivor,只会“浪费”10%的内存空间。
- 标记-整理算法
概述:标记-复制算法不适用于新生代,标记-整理算法是针对老年代提出的。将存活的对象都向内存空间一端移动,然后清除其他对象
缺点:移动存活对象并更新所有引用这些对象的地方是一种极为负重的操作,必须全程暂停用户应用程序才能进行,称为“Stop The World”。