在运行时更新Java线程的堆栈大小

5
有没有办法在运行时动态增加主线程的堆栈大小?另外,我认为这是同样的问题,是否可以在实例化后增加/更新Thread的堆栈大小? Thread的构造函数允许定义其堆栈大小,但我找不到任何更新它的方法。实际上,在JDK中我没有找到任何关于堆栈大小的管理(这似乎表明这是不可能的),一切都是在VM中完成。
根据java语言规范,在创建堆栈时设置堆栈大小是可能的,但有一个注释: Java虚拟机实现可能提供程序员或用户控制Java虚拟机堆栈的初始大小,以及在动态扩展或收缩Java虚拟机堆栈的情况下,控制最大和最小大小。 在我看来这并不是非常清楚,这是否意味着某些VM处理具有给定范围内演变的max (edit)堆栈大小的线程?我们可以用Hostpot做到这一点吗(除了Xss之外,我没有找到任何与堆栈大小相关的选项)?
谢谢!

你有查看过这个问题吗?https://dev59.com/CXA65IYBdhLWcg3wqQc8 虽然没有直接的答案,但是有关于堆栈大小管理的好讨论。 - kommradHomer
@kommradHomer 这很有趣,但不完全是我想要的。我想知道当线程已经在运行时是否可以更新堆栈大小(在极端情况下,线程将尝试通过增加其堆栈大小来“适应”,而不是崩溃导致堆栈溢出)。 - Jerome
2个回答

5

栈的大小会随着使用而动态更新,因此您永远不需要操作它。

您可以设置的是最大大小,使用 -Xss 命令。这是虚拟内存大小,您可以在64位JVM上将其设置得多大都可以。实际使用的内存基于您所使用的内存量. ;)

编辑:重要区别在于最大大小被保留为虚拟内存(堆也是如此)。即地址空间被保留,这也是为什么无法扩展的原因。在32位系统中,您的地址空间有限,这仍可能是一个问题。但在64位系统中,您通常拥有高达256TB的虚拟内存(处理器限制),因此虚拟内存很便宜。实际内存分配在页面(通常为4KB)中进行,并且只有在使用时才会分配它们。这就是为什么Java应用程序的内存似乎会随时间增长,即使在启动时已分配了最大堆大小。线程堆栈也是同样的情况,只有实际使用到的页面才会被分配。


好的,我理解你的意思了。虽然这并没有回答我的问题,但你指出了我提问的原因是错误的。实际上,我认为一旦创建了一个线程,整个堆栈大小(最大值)就被保留了(以防止碎片化或其他问题)。这是不正确的 :) 因此,没有必要创建具有较低最大堆栈大小的线程,期望它们消耗更少的内存,然后调整它们的最大堆栈大小。 - Jerome
能否请Peter解释一下?这是否意味着我可以使用-Xss104K(最小值),而不必担心StackOverflow异常,因为JVM会自动增加每个线程的堆栈大小,使其接近104k?还是说? - kellogs
@kellogs 操作系统在进程使用页面时为其分配页面。如果您将最大值设置为1 MB,但从未使用超过100KB,则操作系统仅为该线程的进程分配100KB的页面。这种方法非常有效,因为不同的线程具有相同的最大值,但堆栈的使用情况不同。 - Peter Lawrey
1
如果是这种情况,那么一定有什么东西逃脱了我的注意。你看,没有-Xss参数,我能够在程序中处理大约11k个线程。加上-Xss104K后,它增加到了30k。仅仅通过这个参数。 - kellogs
1
@kellogs 如果是这样,我猜你正在使用一个有限虚拟内存的32位JVM。如果你使用64位JVM,虚拟内存是便宜的,大部分时间只有真实内存最重要。 - Peter Lawrey
@PeterLawrey 不是的,64位虚拟机。OpenJDK运行环境(IcedTea6 1.12.3)(6b27-1.12.3-0ubuntu1〜11.10.1) OpenJDK 64位服务器虚拟机(版本20.0-b12,混合模式) - kellogs

3

在标准JDK中没有这样的方法,即使stackSize参数也不是固定的:

如果有的话,stackSize参数的影响高度依赖于平台。在某些平台上,stackSize参数的值可能根本没有任何作用。 … 虚拟机可以将stackSize参数视为建议。

(原文中的强调。)


“set in stone” 的意思是最终的吗?是的,如果更新不可能,为什么他们没有将 stackSize 设置为 final 变量呢?我检查了一下 Thread 的 stackSize 变量是否在启动执行后更新过,它从未被更新过(使用值如 -1、0、13)。我不想花几个小时在 openJDK 中进行检查 :s - Jerome
不,我的意思是即使你将 stackSize 传递给 Thread 构造函数,JVM 绝对不会保证关心它。文档明确表示 JVM 可以将您的参数视为建议,或者完全忽略它。 - yshavit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接