【问题标题】:reproduce OutOfMemoryError with -Xss使用 -Xss 重现 OutOfMemoryError
【发布时间】:2019-04-14 11:34:17
【问题描述】:

我正在尝试复制java.lang.OutOfMemoryError: unable to create new native thread 但是使用 -Xss VM 参数。 我猜如果我们有大量线程,并且每个线程占用 X 堆栈空间,如果线程*X > 总堆栈大小,我将遇到异常。 但是什么也没发生。

我的测试员:

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

    ThreadPoolExecutor executor = new ThreadPoolExecutor(1000, 15000, 0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());
    int i = 0;

    try
    {

        Thread.sleep(100);
        for (; i <= 10; i++)
        {
            Runnable t = new Runnable()
            {
                List<Object> objects = new LinkedList<>();

                public void run()
                {
                    while (true)
                    {
                        objects.add(new Object());
                    }
                }
            };

            executor.submit(t);

        }
    }
    catch (Throwable e)
    {
        System.err.println("stop with " + i + " threads, " + e);
        System.err.println("task count " + executor.getTaskCount());
        System.out.println("get active thread count " + executor.getActiveCount());
        executor.shutdownNow();

    }
}

`

我的虚拟机参数是

-Xms512m -Xmx512m -Xss1g

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

谢谢

【问题讨论】:

    标签: java exception jvm out-of-memory


    【解决方案1】:

    在大多数 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;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-26
      • 2019-07-08
      • 2012-11-30
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      相关资源
      最近更新 更多