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