堆栈框架,方法调用和垃圾收集
我正在学习GC。 我开始了解以下关于方法调用的机制:
在JAVA的每个方法调用中,都会创建一个新的Frame并将其推入堆栈。 该框架包含局部变量,操作数堆栈和对常量池的引用。 当任一方法成功完成或方法抛出一个未捕获的异常时,框架将被删除。
还有以下内容:
JVM规范不需要Java堆栈的特定实现。 帧可以从一个堆中单独分配,也可以从连续内存中取出,或者两者兼而有之。
我的问题是:
由于框架是堆栈的一部分。 堆栈是非堆区域的一部分。 如果GC只负责清理堆区,那么如何以及何时堆栈可能驻留或不驻留在堆中的帧将从内存中移除?
如果帧未被GC删除,则必须运行其他某个线程来清除它们。 它是什么? 如果通过GC进行清理,那么这仅仅意味着,如果某个应用程序遇到与GC相关的问题,则不必要的方法调用可能是问题的一部分。
我希望我的问题很清楚。
更新:与此相关的另一个问题:
class GCA {
public static void main(String a[]) {
Object obj = new Object();
}
}
根据我的理解,在上述方法中:
obj
将被分配到Stack Frame的局部变量数组中。 new Object()
将分配在堆上。 obj
驻留的帧所使用的内存不是GC的责任。 当方法返回时,它将被同步完成。 new Object()
将被GC清理。 以上理解是否正确?
由于框架是堆栈的一部分。 堆栈是非堆区域的一部分。 如果GC只负责清理堆区,那么如何以及何时堆栈可能驻留或不驻留在堆中的帧将从内存中移除?
有两种观点。 一个是Java应用程序看待事物的方式。 对象在堆上分配,但是本地变量(即原始值和对这些对象的引用)位于堆栈上。 从这个意义上说,你所做的陈述是正确的:堆栈框架形成堆栈,与堆不同,因此不受垃圾收集影响。
另一种观点是JVM的内部工作方式及其与操作系统的接口。 出于效率原因,即使概念上属于堆,它也可能决定将对象放置在堆栈上。 这是为了逃避分析后的表现。 同样,它可能会决定将概念堆栈的一部分保存在它自己管理的堆分配内存中,而不是JVM本身使用的本地调用堆栈。 这是规范所指的内容:JVM不必在低层编程意义上使用堆栈来实现Java调用堆栈。 但即使它使用操作系统堆,这仍然不属于GC的堆。
如果帧未被GC删除,则必须运行其他某个线程来清除它们。
不可以。只有在帧被异步释放时才需要另一个线程。 但释放一个堆栈帧很容易:只要函数退出,该帧就可以被释放,因为它的所有数据都超出了范围。 因此离开函数的线程负责清理。 异步GC根本不参与。
链接地址: http://www.djcxy.com/p/82741.html