如同上一篇文章提到的,对象的内存位址是自堆(Heap)中取得,而诸如方法中的本地变量(local Variable)是存放在方法桟(Method Stack)中,因为方法中的变量及对象引用存在於堆中的对象,所以所有执行线程方法桟中的变量及对象均称为Root Objects,而在 Graph 中,所有可与 Root Objects 连通的对象,我们称之为 Live Object,如下图所示:
Mark-sweep algorithm 是 free list 内存管理机制中基本的垃圾回收机制。在 JVM 内存不足时,会启动垃圾回收机制:
1。暂停所有其它执行中的线程。
2。自 Root Objects 开始,执行DFS,将所有的引用关系,将对象标注下(Mark)使用中(Live)或不是(Dead)。
3。执行清理(Sweep)将所有未使用的对象(图中的 Non-Reachable Objects)清除,并清除Live Objects的 Mark 标枳,将对象内存位置放回 Free List 中未使用的内存部份。
对比 reference count内存回收机制(Java 中使用 Weak Reference的内存圾垃回收机制)比较起来,mark-sweep algorithm 有至少二个优点:
1。解决循环引用导致无法回收无用对象的问题。比如上图中的 Non-Reachable Objects相互引用时,他们的引用数无法降为0,而导致在 Reference Count机制中无法回收的问题.
2。避免 Reference Count 一旦引用数为0时便触发垃圾回收机制,容易导致过度引发 Context- Switching 的问题 。Mark-sweep algorithm 只在内存不足时由 Java Virtual Machine 触发。
同时, mark-sweep algorithm 还有其它类似的垃圾回收机制,如 mark-compact, mark-copy algorithm 有兴趣的话可以查查相关的文献资料。
refs:
https://blogs.msdn.microsoft.com/abhinaba/2009/01/30/back-to-basics-mark-and-sweep-garbage-collection/
https://plumbr.eu/handbook/garbage-collection-algorithms
http://www.brpreiss.com/books/opus5/html/page424.html
http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/