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堆栈大小。

以下因素在识别最大线程限制方面起着非常重要的作用: –

  1. 处理虚拟地址限制( 32-bit架构为2^64 64-bit架构为2^64
  2. Java堆栈大小(可以通过命令java -XX:+PrintFlagsFinal -version | grep -iE 'ThreadStackSize'确定java -XX:+PrintFlagsFinal -version | grep -iE 'ThreadStackSize'
  3. 最大PID限制(可通过命令“cat / proc / sys / kernel / pid_max”确定)
  4. 最大进程限制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(); } } }