Java linux中的最大线程数

Java linux中的最大线程数,java,linux,jvm,Java,Linux,Jvm,我使用下面的代码来测试线程的最大数量,但它非常奇怪 import java.util.concurrent.atomic.AtomicInteger; public class TestThread extends Thread { private static final AtomicInteger count = new AtomicInteger(); public static void main(String[] args) { try{

我使用下面的代码来测试线程的最大数量,但它非常奇怪

import java.util.concurrent.atomic.AtomicInteger;

public class TestThread extends Thread {
    private static final AtomicInteger count = new AtomicInteger();

    public static void main(String[] args) {
        try{
            while (true) {
                (new TestThread()).start();
            }
        } catch (Error | Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Override
    public void run() {
        System.out.println(count.incrementAndGet());
        while (true)
            try {
                Thread.sleep(Integer.MAX_VALUE);
            } catch (InterruptedException e) {
                break;
            }
    }
}
操作系统是ubuntu:18.04,内存是4G,处理器数量是2。 JDK:openjdk1.8.0_252

java-Xss1m-Xms1024m-Xmx1023m测试线程

java-Xss512k-Xms1024m-Xmx1023m测试线程

java-Xss1m-Xms2048m-Xmx2048m测试线程

因此,线程数始终等于10000个左右

  • 为什么结果是一样的
  • 我在命令中设置了-Xss1m,这是否意味着每个线程将只有1m内存? 如果它只有一个内存,第10000个线程将有10G内存,实际上机器中只有4G内存

  • -Xss
    确定Java线程的最大堆栈大小。当线程启动时,操作系统会为这个大小的堆栈创建一个虚拟内存区域,但内存不会立即分配到物理RAM中

    物理页在对页的第一次内存访问时被延迟分配。只要线程不调用deep方法,它们就不会使用所有堆栈空间。这就是为什么无论设置了什么
    -Xss
    ,RAM中只分配了几个底层堆栈页面的原因

    Linux默认启用。这意味着,它允许提交比物理RAM数量更多的虚拟内存(只要该虚拟内存实际上没有物理页支持,就像您的情况一样)

    因此,在您的情况下,抛出
    OutOfMemoryError
    不是因为堆栈空间,而是因为其他操作系统限制之一:

    • ulimit-u
    • sysctl kernel.pid\u max
    • sysctl内核.threads max
    另见:


    1。它记录了什么错误消息?2.您有多少总内存(ram+交换)?错误消息是无法创建新的本机线程。我在ubuntu中打印顶部。KiB内存:总计4015860,免费1923636,使用1429424,缓冲/缓存662800;KiB Swap:1942896总计,1942896免费,0使用,2336928可用Memulimit-u是15511这很有趣,有几个因素可以限制您可以创建的线程数量,但很难说您正在使用哪一个。您看到生成的hs_err_pid日志文件了吗?回答得很好!您提到的最后一个链接()也谈到了
    /proc/sys/vm/max\u map\u count
    -这在内核文档()中被记录为“一个进程可能拥有的最大内存映射区域数”,但我不确定这与一个进程可以创建的最大线程数是如何对应的-您对此有任何详细信息吗?是否为进程创建的每个线程创建了最少数量的“映射”?@JurajMartinka通常每个线程堆栈有两个内存映射:一个用于可访问堆栈区域,另一个用于可访问堆栈区域。碰巧,可访问的堆栈区域可以与具有相同属性的相邻映射(RW访问的匿名映射)组合,但通常
    max\u map\u count
    的线程数应该严格超过预期线程数的2倍。感谢@apangin,需要更多时间来查看这些消息。