Не удается пройти 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
и доложить результаты.