Не удается пройти 2542 потока в Java на 4 ГБ iMac OSX 10.6.3 Snow Leopard (32 бита)

Я запускаю следующую программу, пытаясь выяснить, как настроить мою JVM для получения максимального числа потоков, которые может поддерживать моя машина. Для тех, кто может не знать, Snow Leopard поставляется с Java 6.

Я попытался запустить его со значениями по умолчанию, и в следующих командных строках я всегда получаю сообщение об ошибке нехватки памяти в потоке 2542 независимо от того, какие параметры JVM установлены.

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

независимо от того, что я передаю, я получаю те же результаты, Ошибка нехватки памяти на 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.

4 ответа

Решение

2542 выглядит как произвольное число:

Я закрыл все программы, кроме одного окна терминала, из которого я выполнял свой тест, и я получил 2545, который сказал мне, что это был произвольный предел.

Чтобы получить количество потоков для OSX 10.6.3, вы должны:

> sysctl kern.num_threads
kern.num_threads: 2560

а также

> sysctl kern.num_taskthreads
kern.num_taskthreads: 2560

2560 номер совпадает с 2542 а также 2545 потому что, очевидно, в фоновом режиме работают другие потоки. Согласно официальной документации kern.num_taskthreads не может быть настроено в настольной версии OSX.

Как вы думаете, у вас будет много потока одновременно до 1 часа? Я так не думаю. Я работал в приложении, которое обрабатывало сотни документов, конвертировало их из и в diff. формат, генерирует правильные журналы в БД и хранит конкретную информацию также. Тогда также это закончилось в секундах.

То, что вы должны позаботиться об этом, кодировать разумно, чтобы не создавать слишком много потоков. Вместо этого используйте ThreadPool предоставляется Java, так что те же потоки могут быть использованы при необходимости. это обеспечит лучшую производительность. Также сохраняйте синхронизацию на минимальных блоках, чтобы избежать узких мест при выполнении.

Благодарю.

Согласно документации Apple Developer, размер стека потоков должен быть не менее 64 КБ, поэтому ваш -Xss 1014 игнорируется. Но даже при 64 КБ на поток потребление памяти стека потоков составляет всего около 160 МБ, так что это не должно быть проблемой. Потоки могут также потреблять память из более ограниченного пула, или может просто быть ограничение на количество потоков, которое вы можете иметь на процесс или пользователя.

Вам необходимо выяснить максимальное количество потоков, поддерживаемых операционной системой в вашей системе.

На Linux вы можете сделать что-то вроде:

cat /proc/sys/kernel/threads-max

чтобы получить максимум и установить его, вы можете сделать что-то вроде:

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

Также попробуйте запустить с:

-XX:-UseBoundThreads

и доложить результаты.

Другие вопросы по тегам