Java的堆栈是分配大小的物理还是逻辑?

时间:2012-02-25 17:19:50

标签: java memory jvm profiling stack

我想知道我们认为Java所拥有的堆栈分配大小(例如,512k)是否是逻辑大小(意味着实际上我们使用的数据超过512k,包括所有Hotspot开销),或者是一个物理限制(意味着总结堆栈中所有Java分配的东西不会超过512k这样的东西)?

我会说,很难通过测试来解决这个问题,正如我在其他帖子中看到的那样:Inferring a method's stack memory use in Java

如果可能,我想要某种来源!

由于

2 个答案:

答案 0 :(得分:2)

我认为在这种情况下,物理和逻辑之间的区别有点模糊。由于HotSpot会随意将您的代码JIT转换为本机代码,结果可能取决于许多优化,因此可以认为两种视图都是正确的。

或者,可以说堆栈是物理的,但堆栈上的内容是可变的,并且从执行的Java代码派生出来并不总是很简单。例如,函数调用可以内联或不内联,因此从一个地方调用您的函数可能需要堆栈上的额外空间,并且从另一个地方或在其他时间调用相同的函数可能不需要它或者需要更少(或者更多)。这在this document中被称为深层内嵌。如果将引用推送到堆栈,它们的大小也可能会有所不同(有些技巧可以有时将引用压缩到32位,即使在64位JVM中也是如此)。由于JIT编译器异步工作并根据代码执行中的分析数据做出一些决策,因此相同的代码可能具有不同的性能,并且可能还会在不同的运行期间堆栈使用。

修改 垃圾收集器,JIT编译器等在不同的线程中运行,因此它们使用自己的调用堆栈,如果这就是“HotSpot开销”的含义。

答案 1 :(得分:2)

堆栈大小使用虚拟内存直到实际使用。这意味着每个线程的堆栈大小可能为1 MB,但常驻大小可能只有32 KB。

这是因为操作系统会在您实际使用它们时为您的程序分配页面(通常为4 KB)。

e.g。它在启动时分配你的最大堆大小,但是你的程序在使用每一页之前都不会使用那么多主内存。

您可能很难专门为JVM查找此信息,因为这是操作系统提供的功能,所有程序都以这种方式工作。即它不是JVM的特殊功能。