在 4GB iMac OSX 10.6.3 Snow Leopard(32 位)上无法通过 Java 中的 2542 个线程

Posted

技术标签:

【中文标题】在 4GB iMac OSX 10.6.3 Snow Leopard(32 位)上无法通过 Java 中的 2542 个线程【英文标题】:Can't get past 2542 Threads in Java on 4GB iMac OSX 10.6.3 Snow Leopard (32bit) 【发布时间】:2011-02-21 02:22:22 【问题描述】:

我正在运行以下程序,试图弄清楚如何配置我的 JVM 以获得我的机器可以支持的最大线程数。对于那些可能不知道的人,Snow Leopard 附带 Java 6。

我尝试使用默认值和以下命令行启动它,无论 JVM 选项设置为什么,我总是在线程 2542 处出现内存不足错误。

java TestThreadStackSizes 100000
java -Xss1024 TestThreadStackSizes 100000
java -Xmx128m -Xss1024 TestThreadStackSizes 100000
java -Xmx2048m -Xss1024 TestThreadStackSizes 100000
java -Xmx2048m -Xms2048m -Xss1024 TestThreadStackSizes 100000

无论我通过什么,我都会得到相同的结果,Out of Memory Error at 2542

public class TestThreadStackSizes

    public static void main(final String[] args)
    
        Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() 
            public void uncaughtException(final Thread t, final Throwable e)
            
                System.err.println(e.getMessage());
                System.exit(1);
            
        );
        int numThreads = 1000;
        if (args.length == 1)
        
            numThreads = Integer.parseInt(args[0]);
        

        for (int i = 0; i < numThreads; i++)
        
            try
            
                Thread t = new Thread(new SleeperThread(i));
                t.start();
            
            catch (final OutOfMemoryError e)
            
                throw new RuntimeException(String.format("Out of Memory Error on Thread %d", i), e);
            
        
    

    private static class SleeperThread implements Runnable
    
        private final int i;

        private SleeperThread(final int i)
        
            this.i = i;
        

        public void run()
        
            try
            
                System.out.format("Thread %d about to sleep\n", this.i);
                Thread.sleep(1000 * 60 * 60);
            
            catch (final InterruptedException e)
            
                throw new RuntimeException(e);
            
        
    

关于如何影响这些结果的任何想法?

我编写这个程序是为了弄清楚 Windows Server 2003 的能力,因为我得到这些out of memory can't create native threads 的数量非常少,比如几百个。我需要看看一个特定的盒子能用不同的-Xss 参数做什么,然后我在 OSX 上遇到了这个任意限制。

【问题讨论】:

哇,你有多少个 CPU?您在任何时候都只能在 CPU 上运行一个线程(可能是两个)。其余的只是增加开销。如果你认为你需要这么多线程,也许需要重新设计。 谁说我“需要”这么多线程,我只是想知道限制以及如何更改它们。 @PeterLawrey:如果您正在处理 I/O 密集型的工作,例如网络服务器或类似的东西,您通常会有大量空闲的线程在 I/O 上被阻塞。 /O,但仍占用操作系统进程表中的一个插槽。这不一定是他们使用多少 CPU 的问题。 @AdrianPetrescu 确实如此,但是超过 1000 个线程时,即使它们只是阻塞 IO,它们也会开始增加大量负载。 "您在任何时候只能在 CPU 上运行一个线程(可能是两个)。其余的只是增加开销。"这不是真的。至少在 CPU 绑定任务之外的任何事情上都不是这样。对于 IO 绑定任务,您可以拥有数倍于 CPU 的线程数而不会出现任何问题。 【参考方案1】:

您需要找出操作系统在您的系统上支持的最大线程数。

在 linux 上,您可以执行以下操作:

cat /proc/sys/kernel/threads-max

要获得最大值并设置它,您可以执行以下操作:

echo 10000 > /proc/sys/kernel/threads-max

也尝试运行:

-XX:-UseBoundThreads

并报告结果。

【讨论】:

nope not on linux and -XX:-UseBoundThreads 不会改变任何东西【参考方案2】:

根据Apple Developer doc,线程堆栈大小应至少为 64K,因此您的 -Xss 1014 将被忽略。但是即使每个线程有 64K,线程堆栈内存消耗也只有 160MB 左右,所以这应该不是问题。线程也可能从更有限的池中消耗内存,或者可能只是限制每个进程或用户可以拥有的线程数。

【讨论】:

我将它设置为 256k,但它仍然在完全相同的线程数下失败。 java -Xss256k -XX:ThreadStackSize=256 TestThreadStackSizes 10000【参考方案3】:

2542 似乎是一个任意数字:

我关闭了所有程序,除了我运行测试的一个终端窗口,我到达2545,告诉我这是一个任意限制。

要获取 OSX 10.6.3 的线程数,请执行以下操作:

> sysctl kern.num_threads
kern.num_threads: 2560

> sysctl kern.num_taskthreads
kern.num_taskthreads: 2560

2560 数字与25422545 匹配,因为后台显然有其他线程在运行。 根据官方文档kern.num_taskthreads在OSX桌面版中无法调整。

【讨论】:

在 OS X 10.8 和 10.11 上测试 'sysctl kern.num_threads' 数字显示为 10240。它似乎已经增加了。 @JasonFuerstenberg 在 10.11.5 上对我来说相同的数字,但是 sysctl kern.num_taskthreads 给出 2048,我不能在 Java 中创建超过 2023 个线程。 @ErwinBolwidt jvm self也需要创建线程,添加2023就是2048,可以jstack这个进程查看一下。【参考方案4】:

你认为你会在长达 1 小时的时间内同时处理这么多线程吗?我不这么认为。我曾在处理数百个文档的应用程序中工作,将它们从差异转换为差异。格式,在数据库中生成正确的日志并存储特定信息。然后它也在几秒钟内完成。

你应该注意的事情是,明智地编码以避免产生过多的线程。而是使用 Java 提供的ThreadPool,以便在需要时可以使用相同的线程。这将提供更好的性能。还要在最小块上保持同步以避免执行中的瓶颈。

谢谢。

【讨论】:

以上是关于在 4GB iMac OSX 10.6.3 Snow Leopard(32 位)上无法通过 Java 中的 2542 个线程的主要内容,如果未能解决你的问题,请参考以下文章

iMac 上的 XAMPP - 它会对内置的 Apache、Perl、PHP 产生不利影响

在 OSX 上的核心配置文件上获取可用的 opengl 扩展

Mac OSX系统下的渗透利用工具Empyre

mac格式化磁盘选择哪个格式

主机文件如何只允许一个域名

mac格式化移动硬盘啥格式最好