Я арендую виртуальную машину под управлением Ubuntu 9.04. Я установил SUN JDK 6.0 (через apt-get) и Tomcat 6.0.18 (через разархивирование).
Сначала было невозможно запустить JVM из-за проблем с памятью. Даже что-то простое, как java -version
потерпел неудачу с
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
Я понял это, хотя free
сообщил о 44 ГБ свободной памяти, мне разрешили использовать только небольшую часть, примерно 284 МБ на одно выделение. Бег java -Xms10m -Xmx256m -version
работает нормально, но я не хочу изменять каждый скрипт, вызывающий java.
Также я читал о JAVA_OPTS
переменная среды, которую уважают многие приложения. Я установил это на "-Xms10m -Xmx256m"
Сценарий запуска tomcat catalina.sh
также использует JAVA_OPTS
. Но, тем не менее, я все еще получаю три упомянутые выше строки ошибок, которые можно прочитать в logs/catalina.out
. Я знаю, что используется JAVA_OPTS, потому что, когда я добавляю бессмыслицу в эту переменную, я вижу последствия в logs/catalina.out
.
Похоже, Tomcat также хочет запустить javac, которому нужны параметры с префиксом -J
лайк -J-Xms10m -J-Xmx256m
вместо. Но я не уверен, связано ли это с проблемой, потому что вывода не больше, чем этих трех строк.
Я запускаю Tomcat через bin/startup.sh
который, в свою очередь, вызывает bin/catalina.sh
. Я знаю, что есть возможность запустить его через jsrv
, но я не могу этого сделать, потому что процесс создания / настройки для jsrv
также хочет позвонить javac
который не работает с известным трехстрочным сообщением об ошибке, упомянутым выше.
Теперь меня бы интересовали два возможных решения:
java
или javac
и как он это называет?PS: Обратите внимание, что у меня есть контроль только над виртуальной машиной, но нет контроля и только ограниченные знания относительно окружающей физической машины.
PPS: Извините за нубское название этого вопроса, но я чувствовал, что оригинальный, хорошо написанный заголовок не привлекает достаточно читателей, поэтому я подумал, что это может помочь;) Это действительно помогло, так как я получил 0 просмотров в первый час, но 8 просмотров через час после изменения. Странный мир.
Изменить: это результат ulimit -a
:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 20
file size (blocks, -f) unlimited
pending signals (-i) 16382
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
javac
обычно порождает отдельный процесс, который должен подпадают под разные правила процесса.
-J
параметры предназначены для передачи аргументов через оболочку / средство запуска в JVM, я не видел этого на Tomcat.
Узнайте, откуда берется -Xmx:
find /your/install/dir/with/tomcat |xargs grep '-Xmx'
Однажды у меня была аналогичная проблема. Вы можете попробовать запустить Java с помощью
vm.overcommit_memory = 1
устанавливается в /etc/sysctl.conf. Или просто эхо "1" > /proc/sys/vm/overcommit_memory
Или поиграйте с overcommit_memory, overcommit_ratio http://www.redhat.com/magazine/001nov04/features/vm/
Вы также можете проверить java vms, которые вы установили. Убедитесь, что проблема не в среде gcj.
пытаться
update-java-alternatives -l
чтобы узнать, является ли sun-java6 вашим значением по умолчанию. Отбросьте «-l», чтобы увидеть другие параметры этой команды, например как изменить значение по умолчанию.
Если я правильно помню, все java-проблемы, которые у меня были на ubuntu, имели корень в gcj, который был по умолчанию (он мог входить как некоторая зависимость до sun-java6). Если я не правильно помню, это по крайней мере большинство проблем.
И последнее, но не менее важное (и только связанное с вашим вопросом): вы можете поместить файл с именем "setenv.sh" в каталог bin tomcat. Этого файла нет, но он будет прочитан при запуске, если он будет найден. Здесь вы можете внести все свои изменения, чтобы использовать их позже. Единственный незначительный недостаток заключается в том, что они будут прочитаны при запуске, а также при завершении работы.
Из-за отсутствия альтернатив я попробовал грязный прием: замена java
и javac
с помощью сценариев оболочки, которые обеспечивают передачу правильных аргументов и позволяют мне видеть точный список параметров. Поскольку это уже попытка найти очень конкретное решение, а не часть вопроса, мне захотелось включить его в ответ.
Я искал все случаи java
в моей файловой системе. Было много способов, потому что у меня на машине несколько JRE и JDK. Даже после удаления всех версий, кроме одной, их по-прежнему было много. я использовал find / -name "java" |xargs file
чтобы узнать, какой настоящий один. Он сказал мне:
/var/lib/dpkg/alternatives/java: ASCII text
/etc/alternatives/java: symbolic link to `/usr/lib/jvm/java-6-sun/jre/bin/java'
/usr/share/java: directory
/usr/lib/jvm/java-6-sun-1.6.0.16/bin/java: symbolic link to `../jre/bin/java'
/usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.4.0, not stripped
/usr/bin/java: symbolic link to `/etc/alternatives/java'
Так что я знал, что /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java
был исполняемым файлом. Я переименовал его в javaexec
и разместил сценарий оболочки в его старом месте:
mv /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/javaexec
nano /usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/java
(see below for file contents)
chmod +x #!/bin/bash -e
Это гарантирует, что каждый вызов java
в конце указывает на мой скрипт, который вызовет исполняемый файл с правильными параметрами. После этого я делал подобные ужасные вещи с javac
. Содержание моего скрипта:
#!/bin/bash -e
line=""
for i in $*
do
if [[ "$i" == *Xmx* ]]; then
echo "Seen -Xmx and removed"
elif [[ "$i" == *MaxPerm* ]]; then
echo "Seen -XX:MaxPermSize and removed"
else
line="$line $i"
fi
done
exec="/usr/lib/jvm/java-6-sun-1.6.0.16/jre/bin/javaexec -Xms10m -Xmx100m $line"
echo Now executing $exec
$exec
Он удаляет каждый параметр из командной строки, который включает -Xmx
или что-то вроде -XX:MaxPermSize
и устанавливает собственные ограничения -Xms и -Xmx.
Когда я запускаю Tomcat, он все равно терпит неудачу, но, наконец, JVM запускается, что-то делает, а затем выходит с содержательным сообщением. Катушка не удалась, но она оставляет меня гораздо более довольным, поскольку с этого момента я знаю, что делать. Хотя Tomcat все еще не запускается, у него есть приятный побочный эффект:
Теперь я наконец могу позвонить java
или javac
в командной строке или из скрипта, и они не дают сбоев, что раньше было невозможно вообще! Они только бегать! Эй, я чувствую себя королем слова, я наконец-то получил java для работы на машине с 44 ГБ оперативной памяти, не жалуясь на недостаток памяти. Это действительно великий день в истории компьютеров!
Попробуйте бежать ulimit -v unlimited
перед запуском tomcat. Если это сработает, вы, вероятно, можете добавить это в один или оба сценария запуска или в /etc/profile
, ~/.bashrc
или какой-нибудь другой сценарий профиля оболочки.