用-Xss重现OutOfMemoryError

时间:2018-11-11 15:51:34

标签: java exception jvm out-of-memory

我正在尝试复制trying http://msn.com Success 446035 trying https://google.com Sucess 234077 trying https://www.nasdaq.com/markets/stocks/symbol-change-history.aspx?sortby=EFFECTIVE&page=1 Traceback (most recent call last): ... TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond trying https://yahoo.com Success 642758 但是使用 -Xss VM参数。 我猜想,如果我们有大量线程,并且每个线程都占用X个堆栈空间,那么如果thread * X>总堆栈大小,我将出现异常。 但是什么也没发生。

我的测试人员:

` 公共静态void main(String [] args)引发异常 {

java.lang.OutOfMemoryError: unable to create new native thread

`

我的VM参数是

  

-Xms512m -Xmx512m -Xss1g

有人知道为什么我没有例外吗?以及我该如何拒绝?

谢谢

1 个答案:

答案 0 :(得分:3)

在大多数OSE上,堆栈是延迟分配的,即,只有您实际使用的页面才变为实际内存。根据所使用的操作系统,每个进程的虚拟内存限制为128到256 TB,因此每个线程1 GB的虚拟内存至少需要128k线程。我会尝试更大的堆栈。例如。 256克

编辑:自己尝试一下,看起来它忽略4g及以上的堆栈大小。在Windows上,最大尺寸为-Xss4000m。

试图在Windows上重现此错误,在抛出任何异常之前,它似乎使计算机超载。

这是我尝试过的。使用-Xss4000m运行时,它有20多个线程(在我的Windows笔记本电脑停止工作之前,总共有80g)

您可能会在Linux中发现它会在机器过载之前达到ulimit

import java.util.concurrent.*;

class A {
    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor pool = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<>());
        try {
            for (int i = 0; i < 100; i++) {
                System.out.println(i);
                pool.submit(() -> {
                    try {
                        System.out.println(recurse() + " size " + pool.getPoolSize());
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                    return null;
                });
                Thread.sleep(1000);
            }
        } finally {
            pool.shutdown();
        }
    }

    static long recurse() {
        try {
            return 1 + recurse();
        } catch (Error e) {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
            return 1;
        }
    }
}