17

该测试显示了可以在 Java 中创建的最大线程数

    System.out.println("Max memory  " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "M");
    for (int i = 0;; i++) {
        Thread t = new Thread() {
            public void run() {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                }
            };
        };
        try {
            t.start();
        } catch (Error e) {
            System.out.println("Max threads " + i);
            e.printStackTrace();
            System.exit(1);
        }
    }

当我使用默认堆大小(256M)运行它时,我得到

Max memory  247M
Max threads 2247
java.lang.OutOfMemoryError: unable to create new native thread
    at java.lang.Thread.start0(Native Method)
    at java.lang.Thread.start(Thread.java:691)
    at test.Test1.main(Test1.java:19)

当我将最大堆大小增加到 512M 我得到

Max memory  494M
Max threads 1906
...

当我将最大堆大小增加到 1024M 我得到

Max memory  989M
Max threads 1162
...

也就是说,更多的堆内存更少的线程。这是为什么?

4

2 回答 2

18

每个线程都需要一个堆栈。分配给堆的内存越多,留给堆栈的内存就越少。

如果您使用的是 32 位 JVM,这将特别严重,因为该进程对于所有内容(代码、堆、堆栈等)的地址空间将不超过 4GB 。我无法在我的 64 位机器上重现此行为,其中“最大线程”保持不变,无论我为堆分配多少内存。

值得注意的是,许多操作系统允许您调整堆栈的大小。在 Unix 上,这是使用ulimit -s.

于 2013-04-21T07:58:03.183 回答
0

我猜想增加堆大小(并使用全部)会降低操作系统可用于创建新线程的内存量,因此它不能像以前那样创建尽可能多的线程。

于 2013-04-21T07:54:17.947 回答