我正在学习GC。我了解到有关方法调用的以下机制:
在JAVA中的每个方法调用时,都会创建一个新的Frame并将其推入堆栈。该帧包含局部变量、操作数堆栈和对常量池的引用。当方法成功完成或方法抛出未捕获的异常时,将删除该帧。
同时还有以下信息:
JVM规范不需要Java堆栈的特定实现。帧可以从堆中单独分配,也可以从连续的内存中获取,或者两者兼而有之。
我的问题是:
由于Frame是Stack的一部分。Stack是Non-Heap区域的一部分。如果GC只负责清理堆区域,那么如何以及何时从内存中删除可能驻留在堆中的堆栈帧?
如果Frames不是由GC删除的,则必须有其他线程运行以清理它们。那是什么?
如果它们是由GC清除的,那么这意味着如果应用程序遇到与GC相关的问题,则不必要的方法调用可能是问题的一部分。
我希望我的问题很清楚。
更新: 另一个与此相关的问题:
根据我的理解,在上述方法中:
在JAVA中的每个方法调用时,都会创建一个新的Frame并将其推入堆栈。该帧包含局部变量、操作数堆栈和对常量池的引用。当方法成功完成或方法抛出未捕获的异常时,将删除该帧。
同时还有以下信息:
JVM规范不需要Java堆栈的特定实现。帧可以从堆中单独分配,也可以从连续的内存中获取,或者两者兼而有之。
我的问题是:
由于Frame是Stack的一部分。Stack是Non-Heap区域的一部分。如果GC只负责清理堆区域,那么如何以及何时从内存中删除可能驻留在堆中的堆栈帧?
如果Frames不是由GC删除的,则必须有其他线程运行以清理它们。那是什么?
如果它们是由GC清除的,那么这意味着如果应用程序遇到与GC相关的问题,则不必要的方法调用可能是问题的一部分。
我希望我的问题很清楚。
更新: 另一个与此相关的问题:
class GCA {
public static void main(String a[]) {
Object obj = new Object();
}
}
根据我的理解,在上述方法中:
- 引用变量
obj
将被分配在堆栈帧的本地变量数组中。 new Object()
将被分配在堆上。- 清理包含
obj
的帧所使用的内存不是垃圾回收的责任。它将在该方法返回时同步完成。 new Object()
将由垃圾回收器清理。
Object
从未传递出该方法,因此可能决定同步释放它。这是一种不改变语义的优化。 - MvG