【问题标题】:Is the Java's stack allocated size physical or logical?Java 的堆栈分配大小是物理的还是逻辑的?
【发布时间】:2012-03-15 19:32:47
【问题描述】:

我想知道我们认为 Java 具有的堆栈分配大小(例如,512k)是否是逻辑大小(这意味着实际上我们使用了超过 512k,例如,包括所有热点开销),或者是物理限制(意味着将堆栈中所有 Java 分配的东西加起来不会达到 512k 之类的东西)?

我想说,通过测试很难弄清楚这一点,正如我在另一篇文章中看到的那样:Inferring a method's stack memory use in Java

如果可能的话,我想要一些来源!

谢谢

【问题讨论】:

    标签: java memory jvm profiling stack


    【解决方案1】:

    堆栈大小在实际使用之前使用虚拟内存。这意味着每个线程的堆栈大小可能是 1 MB,但驻留大小可能只有 32 KB。

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

    例如它会在启动时分配您的最大堆大小,但您的程序在使用每个页面之前不会使用那么多主内存。

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

    【讨论】:

      【解决方案2】:

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

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

      编辑: 垃圾收集器、JIT 编译器等在单独的线程中运行,因此它们使用自己的调用堆栈,如果这就是您所说的“HotSpot 开销”的话。

      【讨论】:

      • 我会尽量让自己更清楚一点。我一直在研究 JDK 和 HotSpot 的代码,我得出的结论是,例如,在进行方法调用时,创建的这个大结构(JavaCallWrapper 就是它的调用方式)充满了所有这些不同的信息,比如参数,返回数据,线程信息等。当然,这个结构存在的事实增加了人们认为存在的更明显的数据(如参数本身,返回数据,this 参数等)。你会为 JVM 定义的堆栈大小“计算”这个 JavaCallWrapper 吗?
      猜你喜欢
      • 1970-01-01
      • 2012-07-29
      • 2014-12-14
      • 1970-01-01
      • 2019-10-25
      • 2012-05-16
      • 2018-02-04
      • 2016-08-26
      相关资源
      最近更新 更多