我需要一些关于如何最好地调整内存设置以允许更多线程的输入。
我读了How many threads can a Java VM support?上的冒充并在那里跟着java示例(dieLikeaDog)它确实有效,在死前产生不到800个线程。
与上面的(dieLikeaDog示例)链接一样,代码生成所有线程,直到出现以下错误:java.lang.OutOfMemoryError:无法创建新的本机线程
在命令行上指定Xss(例如java -Xss104k dieLikeADog)不会改变创建的线程数。
我也尝试更改-Xms和-Xmx,但都没有改变它可以产生的线程数。
确实改变线程数的一件事是我的-u ulimit(对于最大用户进程)。将其设置得更大会增加线程数。
我的ulimits如下:
$ ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 46588
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 1024
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
我有点困惑,因为我在阅读其他示例时认为指定较小的-Xss应该会增加线程数。
是否有其他事情正在阻止Xss工作?
如果重要的话,我使用的是64位fedora 15系统(有6台演出):
OS:
Linux
2.6.42.12-1.fc15.x86_64
amd64
JVM:
Sun Microsystems Inc.
Java(TM) SE Runtime Environment
Java HotSpot(TM) 64-Bit Server VM
1.6.0_27
答案 0 :(得分:1)
-Xss
参数控制为每个线程的堆栈分配的内存量。选择值是平衡堆栈深度与可用内存的情况。设置值-Xss104k
表示将为每个启动的线程的堆栈消耗104KB的可用内存(使用。 -Xmx
设置)如果从 -Xmx1024k
开始,那么在你达到10个线程之前内存将会耗尽,因为1M的内存包括堆和类(permgen)以及线程堆栈。
我的方法是首先检查要在线程中运行的代码。递归繁重的代码需要更多的堆栈。只迭代大量数据的代码可能只需要很少的堆栈。
平衡所涉及的力量的经验方法是减少-Xss
,直到得到StackOverflowError
。这意味着您的线程正在耗尽堆栈。添加一些填充到最后一个有效的值。如果不导致StackOverflowError
的最后一个值是'-Xss1k , the try
- Xss2k or
- Xss3k . If the stack is wiping out at something like
10k I'd try just bumping to
15k`。
现在你有一个线程堆栈的大小。您的总内存( -Xmx
)减去permgen,减去所需的堆数量,可以为您提供线程剩余的内存。如果你需要1000K的堆和50K的permgen,并且你认为堆栈大小为2K,那么要运行十个线程,你将-Xmx1070K
视为最小内存。
那说,看看你想要完成什么。为什么需要更多线程?也许答案不是更多的线程,而是一种不同的算法,可以在使用更少的线程时更快地处理数据。
<强>更新强>
我已经删除了我发现的错误的部分原始答案。
堆栈空间不是从堆空间中获取的,它们是单独分配的。 线程堆栈和堆都计入进程的虚拟内存。减少堆允许更多线程,并且增加它允许更少。
在32位JVM上,我能够将堆栈大小减小到1K。 在64位JVM上,104K是最小值。
我在带有4G内存和2个内核的64位Windows 7机箱上进行了一些测试。
使用32位JVM -Xss8k
和-Xmx128m
,程序为我提供了~5000个线程。这似乎是最好的情况。我没有找到可以增加超过该点的线程数的选项组合。如果我增加了堆大小,则最大线程会下降。线程堆栈大小似乎可能与系统页面大小有关,因为如果我选择的堆栈少于8k,则最大线程实际上会变得更糟。
~5000线程限制似乎也适用于Ubuntu Quantal上的32位JVM。
使用64位JVM,这是一个完全不同的故事。使用-Xss104k
和-Xmx128m
,程序超过50000个线程。那时Windows 真的不开心。它停止响应几分钟,然后开始杀死其他进程。我猜想要释放更多的记忆。
<强>更新强>
对Ubuntu的更多测试:我发现我有一个虚拟内存的ulimit。在ulimit -v unlimited
之后,该程序可以达到~36000个线程。
答案 1 :(得分:0)
原因可能在于您提供的ulimits:
max user processes (-u) 1024
每个线程都将计入此值。因为您不仅运行JVM,而且已经从该值中扣除了很多线程。
尝试执行
ulimit -u 4000
并重新运行测试(在你执行命令的shell中!),你可以创建的线程数不应该增加。