воспроизвести OutOfMemoryError с -Xss - PullRequest
0 голосов
/ 11 ноября 2018

Я пытаюсь воспроизвести java.lang.OutOfMemoryError: unable to create new native thread Но с аргументом -Xss VM. Я предполагаю, что если у нас большое количество потоков, и каждый поток занимает пространство стека X, у меня будет исключение, если потоки * X> общий размер стека. Но ничего не произошло.

мой тестер:

` public static 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();

    }
}

`

И мои аргументы VM

-Xms512m -Xmx512m -Xss1g

Есть идеи, почему у меня нет исключения? и как мне отрицать это?

спасибо

1 Ответ

0 голосов
/ 11 ноября 2018

В большинстве операционных систем стек распределяется лениво, то есть только те страницы, которые вы фактически используете, превращаются в реальную память. Ваш процесс ограничен от 128 до 256 ТБ виртуальной памяти на процесс, в зависимости от используемой ОС, поэтому при 1 ГБ на поток вам нужно как минимум 128 КБ потоков. Я бы попробовал намного больший стек. Например. 256g

РЕДАКТИРОВАТЬ: Попробовать это сам, похоже, он игнорирует размеры стека 4g и выше. Самый большой размер -Xss4000m на окнах.

Попытка воспроизвести это в Windows, и кажется, что она перегружает машину до того, как возникнет какое-либо исключение.

Это то, что я пытался. Запустив -Xss4000m, он получил более 20 потоков (всего 80 г, прежде чем мой ноутбук с Windows перестал работать)

Вы можете найти в 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;
        }
    }
}
...