Не удалось пройти 2542 Темы в Java на 4GB iMac OSX 10.6.3 Snow Leopard (32 бит)

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

Я попытался запустить его с настройками по умолчанию и следующими командами, я всегда получаю ошибку Out of Memory в потоке 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.

Ответ 1

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.

Ответ 2

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

Ответ 3

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

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

cat /proc/sys/kernel/threads-max

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

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

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

-XX:-UseBoundThreads

и отчитайте результаты.

Ответ 4

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

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

спасибо.