Первое, что мы должны иметь в виду, это: JVM process heap (OS process) = Java object heap + [Permanent space + Code generation + Socket buffers + Thread stacks + Direct memory space + JNI code + JNI allocated memory + Garbage collection]
, где в этом «наборе» permSpace обычно самый большой кусок.
Учитывая это, я полагаю, ключом здесь является опция JVM -XX:MinFreeHeapRatio=n
, где n от 0 до 100, и это указывает, что куча должна быть расширена, если меньше, чем n%
кучи свободно. Обычно это 40 по умолчанию (Sun), поэтому, когда JVM выделяет память, этого становится достаточно, чтобы получить 40% свободного ( это не применимо, если у вас есть -Xms == -Xmx ). Его «двойная опция» -XX: MaxHeapFreeRatio обычно по умолчанию равен 70 (вс).
Таким образом, в JVM Sun соотношение живых объектов в каждой сборке мусора находится в пределах 40-70%. Если после GC освобождается менее 40% кучи, то куча расширяется. Итак, предположим, что вы используете Sun JVM, я бы предположил, что размер «кучи объектов Java» достиг пика около 445 МБ, в результате чего расширенная «куча объектов» составляет около 740 МБ (чтобы гарантировать свободное 40%). , Тогда (куча объектов) + (пространство перманента) = 740 + 250 = 990 Мб.
Может быть, вы можете попытаться вывести детали GC или использовать jconsole, чтобы проверить эволюцию размера кучи.
P.S .: при работе с такими вопросами хорошо публиковать сведения об ОС и JVM.