64 位 Linux 上的 Java 线程堆栈大小

Posted

技术标签:

【中文标题】64 位 Linux 上的 Java 线程堆栈大小【英文标题】:Java thread stack size on 64-bit linux 【发布时间】:2011-10-18 21:07:04 【问题描述】:

我的目标是提出可以并行运行的最大线程数。谷歌向我指出了许多链接,它们通过划分 RAM/StackSize 给出了简单的数学计算。在 64 位 Linux 中,我们将线程堆栈大小定义为 10 MB(ulimit -s = 10240kb),RAM 为 4GB,为操作系统留出 1 GB 空间,根据这个数学计算,我可以拥有大约 300 个线程,但我的测试应用程序很小写到〜32297,然后给出内存不足错误。

我用 -Xss 尝试了不同的值,但这些值对线程数几乎没有任何影响,它仍然与 ~32297 相同)。

这给我的印象是堆栈大小是可变的,由操作系统决定,并在需要时达到我们定义的最大值,但无论我在哪里阅读,它们的堆栈大小都是静态的

我到底错过了什么?

【问题讨论】:

你可能会被内核限制为mentioned here 您可以拥有与处理器或内核一样多的线程来真正并行运行。否则,JVM 调度程序会随意交错它们。 @Joachim :我读了这篇文章,谢谢..你能否建议我的情况是线程最大变量(其值为 81920)背后的决定因素,堆栈大小为 10 MB,RAM 为 4国标。无法通过数学计算得到这些数字 ***.com/questions/34452302/… - 完成所有这些检查后解决了我的问题。 【参考方案1】:

这是因为 pid_max 内核变量默认为 32768,但对于 64 位系统,可能会增加到 4 百万。 解释很简单 1 个线程 = 1 个进程,它将有 1 个 PID(进程 ID),所以没有更多的 pid,没有更多的线程。

【讨论】:

【参考方案2】:

Linux 间接实现了每个进程的最大线程数!!

number of threads = total virtual memory / (stack size*1024*1024)

因此,可以通过增加总虚拟内存或减少堆栈大小来增加每个进程的线程数。但是,在最大虚拟内存等于交换内存的情况下,过多地减小堆栈大小会导致堆栈溢出导致代码失败。

检查你的机器:

总虚拟内存:ulimit -v(默认为无限制,因此您需要增加交换内存来增加)

总堆栈大小:ulimit -s(默认为 8Mb)

增加这些值的命令:

ulimit -s newvalue

ulimit -v newvalue

*将新值替换为您要设置为限制的值。

参考资料:

http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/

【讨论】:

【参考方案3】:

我还发现 Java 中线程的限制约为 32K。如果你有这么多线程,使用不同的方法通常是一个更好的主意。在我的机器上执行 while(true) Thread.sleep(1000) 的 32K 线程将消耗 3 个内核,只是上下文切换。

Java: What is the limit to the number of threads you can create?

【讨论】:

在您分享的链接中,他们提到了 64 位,堆栈大小为 128K,限制为 32,072,堆栈大小为 512K,限制再次为 32,072。你知道为什么堆栈大小对可以创建的线程数没有任何影响吗?【参考方案4】:

尝试使用检查/更改 linux 最大堆栈大小

ulimit -s

同时检查 linux 线程限制

cat /proc/sys/kernel/threads-max  

【讨论】:

cat /proc/sys/kernel/threads-max 是 81920 。我想知道 b/w ulimit -s 和 threads-max 的关系,如果我更改堆栈大小,threads-max 值会更新吗?【参考方案5】:

当限制为地址空间 (2^32) 时,您所阅读的内容仅在 32 位架构中有效。你实际上有这样的东西:Xmx + MaxPermSize + (Xss * 线程数)

对于 64 位架构,您的地址空间不会是限制 (2^64)。您应该像上面所说的那样查看操作系统限制。

【讨论】:

很好,仍然没有答案的问题是,为什么即使将堆栈大小更改为非常大或非常小的值,最大线程数仍保持不变。操作系统是否动态选择堆栈大小?

以上是关于64 位 Linux 上的 Java 线程堆栈大小的主要内容,如果未能解决你的问题,请参考以下文章

BackgroundWorker DoWork 线程的堆栈大小是多少?有没有办法改变它?

为啥 std::thread 缺少基本功能? [关闭]

是否可以在 64 位 java/linux 环境中运行具有 8gb 堆大小的 Weblogic

如何找到导致cpu飙高的线程堆栈信息

XPC 服务:提高工作线程上的堆栈大小

实时监控 Java 中的总线程堆栈大小