java - 堆栈框架、方法调用和垃圾收集

标签 java memory garbage-collection jvm

我正在研究 GC。我开始了解以下有关方法调用的机制:

On every method Invocation in JAVA, a new Frame is created and pushed on stack. This frame contains local variables, operand stack and reference to constant pool. Frame is removed when either method has completed successfully or the method throws an uncaught exception.

还有以下内容:

The JVM specification does not require a particular implementation for the Java stack. Frames could be allocated individually from a heap, or they could be taken from contiguous memory, or both.

我的问题是:

因为 Frame 是 Stack 的一部分。栈是非堆区的一部分。如果 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 清理。

以上理解正确吗?

最佳答案

Since Frame is a part of Stack. Stack is a part of Non-Heap area. If GC only takes care of cleaning Heap Area, then how and when Stack frames which may or may not reside in Heap are removed from memory?

对此有两种看法。一种是 Java 应用程序看待事物的方式。对象在堆上分配,但局部变量(即原始值和对这些对象的引用)在堆栈上。从这个意义上说,您所做的陈述是正确的:堆栈帧形成堆栈,与堆不同,因此不受垃圾收集的影响。

另一种观点是 JVM 的内部工作原理及其与操作系统的接口(interface)。出于效率的原因,它可能决定将一个对象放在堆栈上,即使它在概念上属于堆。这是为了性能,经过逃逸分析。同样,它可能决定将部分概念堆栈保留在它自己管理的堆分配内存中,而不是 JVM 本身使用的 native 调用堆栈。这就是规范所指的:JVM 不必使用低级编程意义上的堆栈来实现 Java 调用堆栈。但即使它使用操作系统堆,它仍然不是受 GC 影响的堆的一部分。

If Frames are not removed by GC, then there must be some other thread running to clean them up.

没有。只有在异步释放帧时才需要另一个线程。但是释放栈帧很容易:只要函数退出,就可以释放栈帧,因为它的所有数据都超出了作用域。因此,离开该函数的线程负责该清理工作。根本不涉及异步 GC。

关于java - 堆栈框架、方法调用和垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18572213/

相关文章:

C++:将映射文件读入矩阵的快速方法

java - 我不明白图像类!我在这里做错了什么?

java - 不可序列化父类的可序列化子类

perl - 为什么 Perl 会按照这种模式重新分配内存?

memory - gensim: pickle 还是不 pickle ?

c# - GC会收集一个带有函数指针的对象吗?

java - spring ConfigurableApplicationContext 内存泄漏

java - 类型 'org/springframework/http/MediaType'(当前帧,堆栈 [1])不可分配给 'org/springframework/util/MimeType'

java - Joda Time : new DateTime(String) vs DateTime. 解析(字符串)

java - 从线程中更改 boolean 变量时,java中的long gc收集