Не удается пройти 2542 потока в Java на 4 ГБ iMac OSX 10.6.3 Snow Leopard (32 бита) - PullRequest
9 голосов
/ 19 мая 2010

Я запускаю следующую программу, пытаясь выяснить, как настроить мою 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 ]

11 голосов
/ 19 мая 2010

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 голос
/ 19 мая 2010

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

0 голосов
/ 21 мая 2010

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

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

спасибо.

0 голосов
/ 19 мая 2010

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

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

cat /proc/sys/kernel/threads-max

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

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

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

-XX:-UseBoundThreads

и сообщить о результатах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...