У меня есть (sparc) сервер Solaris 10 с 16 ГБ оперативной памяти. Есть более чем 4G бесплатно.
Memory: 16G phys mem, 4371M free mem, 8193M swap, 8193M free swap
Я запускаю много java-процессов (я использую 32-разрядную JVM, потому что ни один из них не требует много памяти) и хочу запустить еще один. Но он утверждает, что не хватает памяти.
# /usr/jdk/jdk1.6.0_17/bin/java -version
Error occurred during initialization of VM
Could not reserve enough space for object heap
Я пробовал работать с уменьшенным максимальным размером пула памяти (-Xmx). Затем я постепенно увеличивал потолок, пока он не стал действительно очень высоким. Сколько он должен выделяться без флага -Xmx? В соответствии с эта страница, Я бы не ожидал, что он попытается использовать более 1 ГБ. И все же я могу сделать это более чем в три раза без ошибок.
# /usr/jdk/jdk1.6.0_17/bin/java -Xmx3900m -version
java version "1.6.0_17"
Java(TM) SE Runtime Environment (build 1.6.0_17-b04)
Java HotSpot(TM) Server VM (build 14.3-b01, mixed mode)
Если я подниму его выше этого уровня, я начну получать другие ошибки, но я ожидал бы этого, поскольку в любом случае я приближаюсь к пределу адресного пространства 4G для 32-разрядного процесса.
Что, возможно, здесь может происходить, и как я могу диагностировать это самостоятельно? редактировать: большинство java-процессов работают от имени разных пользователей (не более 10 на пользователя). Но обратите внимание, что я пытаюсь запустить новый процесс (просто java -version) как root.
# ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 10
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 29995
virtual memory (kbytes, -v) unlimited
У меня возникла проблема с коробкой Solaris 10, у которой было много физической памяти, и с проектом, который позволял моему пользователю приложения открывать почти столько процессов и использовать столько памяти, сколько он хотел (планирование реализации управления ресурсами в конфигурации приложения level), и оказалось, что java не может выделить кучу, которая была больше, чем доступное пространство в / tmp, которое в моей конкретной настройке было смонтировано вне "подкачки" и колебалось, иногда позволяя большие кучи, а в других случаях ограничивая его почти до менее 100м. Я еще не решил эту проблему, но методом проб и ошибок (пробуя начальные размеры кучи чуть выше или ниже доступного пространства / tmp), я почти уверен, что следующим шагом будет обеспечение стабильности точки монтирования / tmp.
Очевидно, вам не хватает места для подкачки. Тот факт, что у вас все еще есть свободная оперативная память, не имеет отношения. Solaris не перегружает память, поэтому все резервирования должны поддерживаться виртуальной памятью.
Посмотри на swap -s
output, чтобы получить информацию об использовании виртуальной памяти (также известной как своп).
у вас могут быть ограничения на использование памяти каждым процессом. IIRC, ограничение памяти, установленное ulimit, ограничивает совокупное использование памяти процессом и все его дети. Если вы создали несколько JVM из оболочки, общий совокупный предел дочерних команд оболочки может быть превышен (если установлен такой предел).
Попробуйте ввести ulimit -a, чтобы узнать, какие ограничения у вас действуют.
Чтобы получить более подробную информацию, вы можете запустить java под truss: truss java -version
(в dtrace версия, dtruss, еще один приятный вариант).
Это покажет вам все системные вызовы, которые выполняет java. Самые интересные из них будут происходить ближе к концу, непосредственно перед системными вызовами для вывода сообщения об ошибке. Если это mmap (), дающий ENOMEM, я бы снова посмотрел на вашу ситуацию с памятью - может ли Solaris пострадать от фрагментации памяти?
Я догадываюсь, что это файлы; если вы запускаете несколько других процессов или демонов как root, вы можете приблизиться к пределу по умолчанию.
По умолчанию Solaris вызывает 32-битную JVM, если вы укажете -d64 в качестве первого аргумента JVM, он вызовет sparcv9 (64-битную) версию JVm.
$ /opt/java/jdk1.6.0_16/bin/java -version java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) Server VM (build 14.2-b01, mixed mode) $ /opt/java/jdk1.6.0_16/bin/java -d64 -version java version "1.6.0_16" Java(TM) SE Runtime Environment (build 1.6.0_16-b01) Java HotSpot(TM) 64-Bit Server VM (build 14.2-b01, mixed mode)