JVM中的最大线程数?
Java虚拟机可以维护的最大线程数是多少?
我没有在原始问题中解释这一点,但我试图对JVM进行基准测试,并希望尝试查看它可以同时维护多少个线程。
在循环中创建线程直到抛出exception是一个选项,但是,我想知道是否有更好的方法来执行此操作。
编写一个创建新线程的循环,直到它爆炸为止是最明确的方法。 您可能会发现性能在实际死亡之前会严重降低。
我不知道JVM中是否有任何配置参数或其他内置限制。 我从未在实践中遇到过极限。 当然,迟早你会耗尽内存,也许是其他一些资源。
我怀疑线程数本身没有限制,而是与线程相关的资源。 也就是说,你可能会看到你可以拥有10,000个线程,如果它们只运行一个只有几个字节数据的小类,但当它们各自拥有1000万个字符串的数组时,它会快速下降。
您的操作系统和硬件配置会受到一些限制。
要增加并发线程数,您应该降低默认的stacksize java -Xss 64k
。
- Oracle 32位JVM 默认为每个线程320kb堆栈大小。
- 对于具有2gb可寻址内存的32位JVM,这将为您提供最多6.5k个线程。
- Oracle 64位JVM 默认为每个线程1M堆栈大小。
- 对于每千兆字节的内存,您将使用默认值获得1024个线程。
- 仅适用于Linux:
-
ulimit -a
将为用户进程和内存提供配置的限制 - 你只能在linux
cat /proc/sys/kernel/pid_max
获得32k个唯一的PID – 最多32k个进程。 - 你将只获得255k个线程
cat /proc/sys/kernel/threads-max
-
如果存在限制,则将由操作系统强加,而不是jvm
真正的问题不应该是你可以创建多少线程,而是有效运行多少线程。 太多的线程,你将导致颠簸,太少和更少的计算时间。
首先,问题,你的生活需要多长时间。 短线程不值得努力。 另一方面,大型计算具有完美的意义。
其次,每个线程消耗多少内存。 获取每个线程所需的内存量,并将其除以可用内存量。 你不应该创建比这更多的线程。
第三,您有多少CPU可用。 您不应该创建比CPU更多的线程。 实际上,您应该考虑至少少于一个线程数。 在具有4个CPU的Windows笔记本电脑上,如果需要高效处理,则不应超过3个线程。
最后,你的线程做了什么。 如果它读取和写入硬盘驱动器,那么您可以拥有比CPU数量更多的线程,因为它必须等待设备响应。 在决定线程数时,请考虑以下方法:
public static int recommendedThreadCount() { int mRtnValue = 0; Runtime runtime = Runtime.getRuntime(); long maxMemory = runtime.maxMemory(); long mTotalMemory = runtime.totalMemory(); long freeMemory = runtime.freeMemory(); int mAvailableProcessors = runtime.availableProcessors(); long mTotalFreeMemory = freeMemory + (maxMemory - mTotalMemory); mRtnValue = (int)(mTotalFreeMemory/4200000000l); int mNoOfThreads = mAvailableProcessors-1; if(mNoOfThreads < mRtnValue) mRtnValue = mNoOfThreads; return mRtnValue; }
最大线程数也可以由JVM实现限制,cab可以与Java虚拟机不同,也可以与另一个Java虚拟机不同。 例如,在Jikes RVM中 ,数组用于保存有关线程的信息(请参阅Jikes RVM Scheduler源代码中的第54行)。 在这种情况下,最大线程数不能超过Java中数组的最大大小,大约为2 ^ 32。 但是,在达到2 ^ 32个线程之前,您更有可能达到其他操作系统限制或硬件限制。
最大线程限制主要取决于硬件,操作系统和Java堆栈大小。
以下因素在识别最大线程限制方面起着非常重要的作用: –
- 处理虚拟地址限制(
32-bit
架构为2^64
64-bit
架构为2^64
) - Java堆栈大小(可以通过命令
java -XX:+PrintFlagsFinal -version | grep -iE 'ThreadStackSize'
确定java -XX:+PrintFlagsFinal -version | grep -iE 'ThreadStackSize'
- 最大
PID
限制(可通过命令“cat / proc / sys / kernel / pid_max”确定) - 最大进程限制
ulimit -u
所以最大线程限制将是((进程虚拟地址空间/ java堆栈大小),最大PID
限制,最大进程限制)的MINIMUM
例如,如果Max进程限制为2048
并且它是上述所有三因素中的最小值,则java进程将无法创建超过该进程的线程。
要validation它,可以创建一个简单的Java应用程序,在该应用程序中,他/她可以在循环中创建一个线程并查看它可以进行多少。
例:
private static Object lock = new Object(); private static int counter = 0; public static void main(String[] _args) { while (true) { new Thread(new Runnable() { public void run() { synchronized(lock) { counter += 1; System.err.println("New thread #" + counter); } while (true) { try { Thread.sleep(3000); } catch (Exception _e) { _e.printStackTrace(); } } } }).start(); } } }