chi*_*tom 10 clr stack garbage-collection jvm
现代垃圾收集器(如在CLR,JVM中)使用什么技术来判断哪些堆对象是从堆栈引用的?
具体来说,VM如何从知道堆栈开始的位置解释所有对堆对象的本地引用?
看一下1996 年 8 月的Artima文章Java 的垃圾收集堆;特别是第2页。
任何垃圾收集算法都必须做两件基本的事情。首先,它必须检测垃圾对象。其次,它必须回收垃圾对象使用的堆空间并使其可供程序使用。垃圾检测通常是通过定义一组根并确定从根的可达性来完成的。如果存在一些从根开始的引用路径,执行程序可以通过该引用路径访问该对象,则该对象是可访问的。程序始终可以访问根目录。任何从根可到达的对象都被认为是活动的。不可访问的对象被认为是垃圾,因为它们不再影响程序执行的未来过程。
在 JVM 中,根集与实现相关,但始终包含局部变量中的任何对象引用。在 JVM 中,所有对象都驻留在堆上。局部变量驻留在Java堆栈上,每个执行线程都有自己的堆栈。每个局部变量要么是对象引用,要么是基本类型,例如 int、char 或 float。因此,任何 JVM 垃圾收集堆的根都将包含每个线程堆栈上的每个对象引用。根的另一个来源是加载类的常量池中的任何对象引用,例如字符串。加载的类的常量池可以引用存储在堆上的字符串,例如类名、超类名、超接口名、字段名、字段签名、方法名、方法签名等。
根引用的任何对象都是可到达的,因此是活动对象。此外,活动对象引用的任何对象也是可访问的。程序能够访问任何可访问的对象,因此这些对象必须保留在堆上。任何不可访问的对象都可以被垃圾收集,因为程序无法访问它们。
本文继续探讨不同的垃圾收集策略,包括引用计数收集器、跟踪收集器、压缩收集器和复制收集器。
虽然这篇文章很旧,但今天仍然适用;并没有太大改变。不同收集策略的性能有所改进,但没有新的重大进展。
例如,Oracle HotSpot JVM 有一个新的垃圾优先垃圾收集器,它是一个复制收集器,针对多核处理器和大堆大小进行了性能调整(有关 G1 垃圾收集器的更多信息,请参阅此答案)。
| 归档时间: |
|
| 查看次数: |
993 次 |
| 最近记录: |