1. Overview
1.概述
Throughout the years, the performance of the systems that we use has increased exponentially. Hence, the number of threads that the Java VM supports has increased as well.
多年来,我们所使用的系统的性能成倍增长。因此,Java虚拟机所支持的线程数量也在增加。
But, how many are we actually able to create? The answer isn’t an exact number because it depends on numerous factors.
但是,我们实际上能够创造多少呢?答案并不是一个确切的数字,因为它取决于许多因素。。
We’ll discuss a couple of these factors and how they influence the number of threads that we can create in a Java VM.
我们将讨论这些因素中的几个,以及它们如何影响我们在Java虚拟机中可以创建的线程数量。
2. Stack Memory
2.堆栈内存
One of the most important components of a thread is its stack. The maximum stack size and the number of threads that we create have a direct correlation to the amount of system memory available.
一个线程最重要的组成部分之一是它的堆栈。最大的堆栈大小和我们创建的线程数量与可用的系统内存数量有直接的关系。
Thus, increasing the memory capacity also increases the maximum number of threads that we can run on a system. More details about the stack size can be found in our article Configuring Stack Sizes in the JVM.
因此,增加内存容量也增加了我们可以在系统中运行的最大线程数。关于堆栈大小的更多细节可以在我们的文章配置JVM中的堆栈大小中找到。
Finally, it’s worth mentioning that, since Java 11, the JVM doesn’t aggressively commit all of the reserved memory for a stack. This helps to increase the number of threads that we can run. In other words, even if we increase the maximum stack size, the amount of memory used by the thread will be based on the actual stack size.
最后,值得一提的是,从Java 11开始,JVM不会主动提交堆栈的所有保留内存。这有助于增加我们可以运行的线程数量。换句话说,即使我们增加了最大的堆栈大小,线程使用的内存量也将基于实际的堆栈大小。
3. Heap Memory
3.堆内存
The heap doesn’t directly affect the number of threads that we can execute. But, it’s also using the same system memory.
堆并不直接影响我们可以执行的线程数量。但是,它也在使用同样的系统内存。
Thus, increasing the heap size limits the available memory for the stack, thereby decreasing the maximum number of threads we can create.
因此,增加堆的大小限制了堆的可用内存,从而减少了我们可以创建的最大线程数。
4. Operating System Choice
4.操作系统的选择
When creating a new Java thread, a new native OS thread is created and directly linked to the one from the VM.
在创建一个新的Java线程时,会创建一个新的本地操作系统线程,并直接与来自虚拟机的线程相连。
Therefore, the Operating System is in control of managing the thread.
因此,操作系统控制着对线程的管理。
Moreover, a variety of limits may be applied, based on the type of the operating system.
此外,根据操作系统的类型,可以应用各种限制。
In the following subsections, we’ll cover these aspects for the most common systems.
在以下几个小节中,我们将介绍最常见的系统的这些方面。
4.1. Linux
4.1. Linux
Linux-based systems, at the kernel level, treat threads as processes. Thus, process limits like the pid_max kernel parameter will directly affect the number of threads that we can create.
基于Linux的系统,在内核级别,将线程视为进程。因此,像pid_max内核参数这样的进程限制将直接影响我们可以创建的线程数量。
Another kernel parameter is threads-max, which describes the overall maximum number of threads.
另一个内核参数是threads-max,它描述了线程的总体最大数量。
We can retrieve all these parameters by executing sysctl kernel.<parameter-name>.
我们可以通过执行sysctl kernel.<parameter-name>来检索所有这些参数。
Finally, there’s the limit for the maximum processes per user, retrievable using the ulimit -u command.
最后,还有每个用户的最大进程限制,可以用ulimit -u命令来检索。
4.2. Windows
4.2 窗口
On Windows machines, there’s no limit specified for threads. Thus, we can create as many threads as we want, until our system runs out of available system memory.
在Windows机器上,对线程没有规定限制。因此,我们可以创建任意多的线程,直到我们的系统耗尽可用的系统内存。
4.3. macOS
4.3. MacOS
There are two main limitations on systems that run macOS, defined by two kernel parameters:
在运行macOS的系统上有两个主要限制,由两个内核参数定义。
- num_threads represents the overall maximum number of threads that can be created
- num_taskthreads represents the maximum number of threads per process
The values of these parameters can be accessed by executing sysctl kern.<parameter-name>.
这些参数的值可以通过执行sysctl kern.
One point worth mentioning is that when one of these limits is reached, an OutOfMemoryError will be thrown, which can be misleading.
值得一提的是,当达到这些限制之一时,会抛出一个OutOfMemoryError,这可能会产生误导。
5. Virtual Threads
5.虚拟线程
We can further increase the number of threads that we can create by leveraging lightweight Virtual Threads that come with Project Loom, which is not yet publicly available.
我们可以通过利用Project Loom附带的轻量级虚拟线程来进一步增加我们可以创建的线程数量,这一点尚未公开。
Virtual threads are created by the JVM and do not utilize OS threads, which means that we can literally create millions of them at the same time.
虚拟线程由JVM创建,不利用操作系统线程,这意味着我们实际上可以同时创建数百万个线程。
6. Conclusion
6.结语
In this article, we looked into the most important aspects that might affect the maximum number of threads that can be created in a Java Virtual Machine.
在这篇文章中,我们研究了可能影响Java虚拟机中可创建的最大线程数的最重要方面。
However, in most cases, increasing the limit is unlikely to permanently solve scalability issues. We’ll need to consider rethinking the implementation of the application or even applying horizontal scaling.
然而,在大多数情况下,增加限制不太可能永久地解决扩展性问题。我们需要考虑重新思考应用程序的实现,甚至是应用水平扩展。