为什么要减小 Java JVM 线程堆栈的大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2623453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:04:31  来源:igfitidea点击:

Why reduce the size of the Java JVM thread stack?

javamultithreadingjboss

提问by djangofan

I was reading an articleon handling Out Of Memory error conditions in Java (and on JBoss platform) and I saw this suggestion to reduce the size of the threadstack.

我正在阅读一篇关于在 Java(和 JBoss 平台)中处理内存不足错误情况的文章,我看到了这个减少线程堆栈大小的建议。

How would reducing the size of the threadstack help with a max memory error condition?

减少线程堆栈的大小如何帮助解决最大内存错误情况?

采纳答案by RichieHindle

When Java creates a new thread, it pre-allocates a fixed-size block of memory for that thread's stack. By reducing the size of that memory block, you can avoid running out of memory, especially if you have lots of threads - the memory saving is the reduction in stack size times the number of threads.

当 Java 创建一个新线程时,它会为该线程的堆栈预先分配一个固定大小的内存块。通过减少该内存块的大小,您可以避免内存不足,尤其是当您有很多线程时 - 内存节省是堆栈大小乘以线程数的减少。

The downside of doing this is that you increase the chance of a Stack Overflow error.

这样做的缺点是增加了堆栈溢出错误的机会。

Note that the thread stacks are created outside of the JVM heap, so even if there's plenty of memory available in the heap, you can still fail to create a thread stack due to running out of memory (or running out of address space, as Tom Hawtin correctly points out).

请注意,线程堆栈是在 JVM 堆之外创建的,因此即使堆中有足够的可用内存,由于内存不足(或地址空间不足,如 Tom霍廷正确指出)。

回答by Tom Hawtin - tackline

The problem exists on 32-bit JVMs were address space can get exhausted. Reducing the maximum stack size will not normally decrease the amount of memory actually allocated. Consider 8k threads with 256kB reserved for stack of 1k of 2MB, that's 31 bits of address space (2GB) gone there.

问题存在于 32 位 JVM 上,因为地址空间可能会耗尽。减少最大堆栈大小通常不会减少实际分配的内存量。考虑 8k 线程,其中 256kB 保留给 1k 的 2MB 堆栈,即 31 位地址空间 (2GB) 到那里去了。

The problem all but disappears with 64-bit JVMs (although the actual amount of memory will increase a bit because references are twice as big). Alternatively, use of non-blocking APIs can remove the need for quite so many threads.

这个问题在 64 位 JVM 中几乎消失了(尽管实际内存量会增加一点,因为引用是两倍大)。或者,使用非阻塞 API 可以消除对如此多线程的需求。

回答by luis.espinal

I would try other things (such as changing the survivor ratio or the size of space allocated for class definitions) before trying to change the thread stack size. It is hard to get it right, thus very easy to get a stack overflow error (which is equally fatal as an out of memory error.)

在尝试更改线程堆栈大小之前,我会尝试其他事情(例如更改幸存者比率或为类定义分配的空间大小)。很难做到正确,因此很容易出现堆栈溢出错误(这与内存不足错误同样致命。)



I've never gotten this right even after careful examination. But then again, I might have never encountered a web application/container combination that could be fined-tuned by changing its thread stack size. I've had much better (and non-fatal) results modifying the survivor ratio. But that has been my work experience. In different workplaces and applications, YMMV.

即使经过仔细检查,我也从来没有做对。但话说回来,我可能从未遇到过可以通过更改其线程堆栈大小来微调的 Web 应用程序/容器组合。我在修改幸存者比率方面获得了更好(且非致命)的结果。但那是我的工作经验。在不同的工作场所和应用程序中,YMMV。

回答by Cheeso

There are N threads in a process, and M bytes of memory is allocated for each thread stack. Total memory allocated for stack usage is N x M.

一个进程中有N个线程,每个线程栈都分配了M字节的内存。为堆栈使用分配的总内存为 N x M。

You can reduce total memory consumed by the stack by reducing the number of threads (N), or reducing the memory allocated for each thread (M).

您可以通过减少线程数 (N) 或减少为每个线程分配的内存 (M) 来减少堆栈消耗的总内存。



Often a thread won't use all of the stack. It's pre-allocated "in case" it will be needed later, but if the thread doesn't use a deep call path, or doesn't use recursion, it may not need all of the stack space allocated on its behalf.

通常一个线程不会使用所有的堆栈。它是预先分配的,“以防万一”以后需要它,但如果线程不使用深度调用路径,或者不使用递归,它可能不需要代表它分配的所有堆栈空间。

Finding the optimal stack size can be an art.

找到最佳堆栈大小可能是一门艺术。