У меня проблемы с приложением JRuby (rails), запущенным в tomcat. Иногда для возврата запросов страниц может потребоваться до минуты (даже если журналы rails обрабатывали запрос за секунды, так что это, очевидно, проблема с tomcat).
Мне интересно, какие настройки оптимальны для размера кучи java. Я знаю, что однозначного ответа нет, но я подумал, может, кто-нибудь прокомментирует мою настройку.
Я использую небольшой экземпляр EC2 с оперативной памятью 1,7 г. У меня есть следующие JAVA_OPTS:
-Xmx1536m -Xms256m -XX:MaxPermSize=256m -XX:+CMSClassUnloadingEnabled
Моя первая мысль, что Xmx слишком велик. Если у меня всего 1,7 ГБ и я выделил 1,5 ГБ для java, я чувствую, что у меня будет много страниц. Обычно мой Java-процесс показывает (вверху) 1.1g res memory и 2g virtual.
Я также читаю где-то установка одинакового размера для Xms и Xmx поможет, так как избавит от затрат времени на выделение памяти.
Я не сторонник Java, но мне было поручено разобраться в этой проблеме, и я пытаюсь выяснить, с чего начать. Любые советы приветствуются!
Обновить
Я начал анализировать дампы сборки мусора, используя -XX:+PrintGCDetails
Когда я замечаю эти случайные длительные времена загрузки, журналы gc сходят с ума. последний, который я сделал (на выполнение которого ушло 25 секунд), у меня были строки журнала gc, такие как:
1720.267: [GC 1720.267: [DefNew: 27712K->16K(31104K), 0.0068020 secs] 281792K->254096K(444112K), 0.0069440 secs]
1720.294: [GC 1720.294: [DefNew: 27728K->0K(31104K), 0.0343340 secs] 281808K->254080K(444112K), 0.0344910 secs]
их около 300 по одному запросу !!! Теперь я не совсем понимаю, почему это всегда GC'ng от ~ 28 м до 0 снова и снова.
в дополнение к предыдущим ответам вы также должны принять во внимание PermGen. PermGen не является частью кучи. с вашей текущей конфигурацией ваш java-процесс может составлять до 1792 МБ, что составляет общий объем вашей машины.
Часть вашей проблемы заключается в том, что вы, вероятно, голодаете все другие процессы для барана. Мое общее практическое правило -Xms
и -Xmx
являются следующими:
-Xms : <System_Memory>*.5
-Xmx : <System_Memeory>*.75
Итак, в системах с 4 ГБ это будет: -Xms2048m -Xmx3072m
, а в вашем случае я бы пошел с -Xms896m -Xmx1344
Хотя я не запускал никаких приложений JRuby на Tomcat, я запускал приложения ColdFusion на различных серверах приложений J2EE, и у меня также были похожие проблемы.
В эти часто задаваемые вопросы, вы увидите, что SOracle сообщает, что в 32-битной Windows максимальный размер кучи будет ограничен от 1,4 до 1,6 ГБ. Мне никогда не удавалось добиться такой высокой стабильности, и я подозреваю, что у вас аналогичная конфигурация.
Я предполагаю, что ваши запросы занимают много времени для запуска b / c с таким большим размером кучи, JVM выделила больше физической памяти, чем должна была предоставить Windows, и, таким образом, Windows тратит много времени на подкачку страниц и обратно. память на диск, чтобы она могла предоставить JVM необходимый объем памяти.
Моя рекомендация, хотя и противоречащая интуиции, заключается в том, что вы на самом деле уменьшите максимальный размер кучи примерно до 1,2 ГБ. Вы также можете увеличить минимальный размер, если заметите, что есть замедления в обработке запросов приложения, в то время как JVM должна запрашивать у Windows больше памяти, чтобы увеличить размер своей кучи по мере ее заполнения несобранными объектами.
Я знаю, что уже выбран ответ, но все же вот мое объяснение.
Прежде всего, в используемой командной строке вы уже зарезервировали 1536 мегабайт для кучи Java (-Xmx1536m) и 256 мегабайт для PermGen (-XX: MaxPermSize = 256m). PermGen выделяется отдельно от кучи Java и используется для хранения классов Java, загруженных в JVM.
Эти две области вместе уже в сумме составляют 1792 мегабайта оперативной памяти.
Но в дополнение к этому также требуется оперативная память для загрузки самой JVM (собственный код JVM) и оперативная память для хранения кода, сгенерированного JIT-компилятором.
Я подозреваю, что все это составляет 2 гигабайта виртуальных машин, о которых вы упомянули.
Наконец, вы также должны принять во внимание другие вещи, которые работают на сервере и которым также требуется оперативная память. Вы действительно не упомянули, сколько свопа используется на сервере. Это скажет вам, меняет ли машина местами, и это заставляет приложение медленно реагировать. Вы должны всегда препятствовать тому, чтобы JVM запускала свопинг. Гораздо лучше часто запускать сборщик мусора, чем выделять слишком много кучи и выгружать часть кучи Java.