Различное потребление памяти при схожих конфигурациях

Различное потребление памяти при схожих конфигурациях

У меня есть два разных экземпляра tomcat 7 на двух разных серверах (oracle jdk7) с почти одинаковой конфигурацией оборудования (оба > 24 ГБ ОЗУ). Оба сервера tomcat имеют одинаковую конфигурацию, и на этих серверах развернуты одни и те же веб-приложения. Варианты catalina следующие:

-XX:PermSize=128m -XX:MaxPermSize=512M -Xmx2048m -XX:+CMSIncrementalMode -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC

Во время выполнения нагрузочного теста (нагрузки на REST API с интенсивным параллельным выполнением запросов) один из серверов выдает ошибку java.lang.OutOfMemoryError: Java heap space(вот трассировка стека:http://pastebin.com/wuS1MVCC), другой сервер работает нормально. Понятия не имею, почему так происходит. Кто-нибудь сталкивался с подобной проблемой?

решение1

Происходит следующее: одна из ваших JVM Tomcat пытается превысить выделенную для нее кучу размером в 2048 МБ.

Похоже, вы ищете не только список того, что можно попробовать, но и конкретный ответ. Итак, вот:

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

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

Если проблема возникает после обработки определенного количества запросов независимо от параллелизма, то у вас утечка памяти. Вам нужно найти ее и освободить память.

В любом случае вам очень поможет хороший анализатор памяти кучи. Есть хорошие коммерческие, такие как YourKit Java Profiler, или бесплатные, такие как Eclipse Memory Analyzer. Найдите инструмент, который вам подходит, и научитесь использовать его, чтобы увидеть, что занимает память. Обратите внимание, что вам не обязательно использовать инструмент для запуска вашей программы — если вы запускаете нагрузочный тест на сервере, то вы можете использовать инструмент командной строки jmap из JDK, чтобы захватить дамп кучи в файл, а затем использовать свой инструмент для анализа файла дампа. Инструмент покажет вам, какие объекты занимают место в вашей куче.

решение2

Естьчто-нибудьотличается между двумя системами, иначе поведение не было бы разным. Обратите внимание, что слишком много времени, потраченного на GC, для слишком малого результата также может вызвать ошибку. Работа вблизи пределов кучи приводит к тому, что GC сталкивается с этой проблемой.

Избыточное время сборки мусора и OutOfMemoryError

Параллельный сборщик выдаст OutOfMemoryError, если слишком много времени тратится на сборку мусора: если более 98% от общего времени тратится на сборку мусора и менее 2% кучи восстановлено, будет выдана OutOfMemoryError. Эта функция предназначена для предотвращения работы приложений в течение длительного периода времени с небольшим или нулевым прогрессом из-за слишком малого размера кучи. При необходимости эту функцию можно отключить, добавив опцию -XX:-UseGCOverheadLimit в командную строку.

Связанный контент