Java默认堆栈大小

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (46)

我明白每个线程都有它自己的stack。原始类型和引用保留在堆栈上,并且没有对象保留在堆栈上。我的问题是:

  • 堆栈可以增长多少?(如与参数 - Xms和 - Xmx
  • 我们可以限制其增长吗?
  • 堆栈是否有默认的最小值和最大值?
  • 垃圾收集如何在堆栈上工作?
提问于
用户回答回答于

堆栈可以增长多少?

您可以使用名为的VM选项ss来调整最大堆栈大小。VM选项通常使用-X {选项}传递。因此,您可以使用java -Xss1M将堆栈大小的最大值设置为1M。

每个线程至少有一个堆栈。某些Java虚拟机(JVM)将Java堆栈(Java方法调用)和本机堆栈(VM中的本机方法调用)放入一个堆栈,并使用托管到本机框架(称为M2NFrame)执行堆栈解绕。一些JVM分开保存两个堆栈。Xss在大多数情况下,设置Java堆栈的大小。

对于许多JVM,他们在不同的平台上为堆栈大小设置不同的默认值。

我们可以限制这种增长吗?

发生方法调用时,将在该线程的堆栈上创建新的堆栈帧。堆栈将包含局部变量,参数,返回地址等。在java中,您不能将对象放在堆栈上,只能将对象引用存储在堆栈上。由于数组也是java中的一个对象,因此数组也不会存储在堆栈中。因此,如果通过将参数分组为对象来减少本地基元变量的数量,则可以减少堆栈空间。实际上,我们无法将对象放在java堆栈上的事实会影响性能(缓存未命中)。

堆栈是否有一些默认的最小值或默认的最大值?

正如我之前所说,不同的虚拟机是不同的,可能会改变版本。看到这里

垃圾收集如何在堆栈上工作?

Java中的垃圾收集是一个热门话题。垃圾收集旨在收集堆中不可访问的对象。所以需要可达性的定义。堆栈中的所有内容都包含GC中根集引用的一部分。从每个线程的每个堆栈都可以访问的所有东西都应该被视为活动的。还有一些其他的根集引用像Thread对象和一些类对象。

这只是GC上栈的非常模糊的用法。目前大多数JVM正在使用分代GC。本文对Java GC进行简要介绍。最近我读了一篇很好的文章,谈论.net上的GC。关于oracle jvm的GC非常相似,所以我认为这也可以帮助你。

用户回答回答于

正如你所说,本地变量和引用存储在堆栈中。当方法返回时,堆栈指针会简单地移回到方法启动之前的位置,也就是说,所有本地数据都被“从堆栈中移除”。因此,堆栈上不需要垃圾收集,只发生在堆中。

回答你的具体问题:

  • 看到如何增加堆栈大小
  • 您可以通过以下方式限制堆栈增长:
    • 将许多局部变量分组到对象中:该对象将存储在堆中,并且只有引用存储在堆栈中
    • 限制嵌套函数调用的次数(通常不使用递归)

  • 对于Windows,32位的默认堆栈大小为320k,64位的默认堆栈大小为1024k,请参阅此链接

扫码关注云+社区