Почему не сокращается выделенная память кучи при использовании ниже MaxHeapFreeRatio?

У меня есть задача java-сервера, которая является памятью hogging. Для одного я сомневаюсь, что он когда-либо превышал MinHeapFreeRatio, но это предположение. Более интересно, что GC уменьшает зрелую генерацию до примерно 2%, но никогда не уменьшает выделенную память для кучи.

Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 3221225472 (3072.0MB)

   NewSize          = 268435456 (256.0MB)
   MaxNewSize       = 268435456 (256.0MB)
   OldSize          = 805306368 (768.0MB)
   NewRatio         = 7
   SurvivorRatio    = 8
   PermSize         = 21757952 (20.75MB)
   MaxPermSize      = 176160768 (168.0MB)

Heap Usage:
New Generation (Eden + 1 Survivor Space):
   capacity = 241631232 (230.4375MB)
   used     = 71657320 (68.3377456665039MB)
   free     = 169973912 (162.0997543334961MB)
   29.65565312351675% used
Eden Space:
   capacity = 214827008 (204.875MB)
   used     = 47322984 (45.130714416503906MB)
   free     = 167504024 (159.7442855834961MB)
   22.028414602320392% used
From Space:
   capacity = 26804224 (25.5625MB)
   used     = 24334336 (23.20703125MB)
   free     = 2469888 (2.35546875MB)
   90.78545232273838% used
To Space:
   capacity = 26804224 (25.5625MB)
   used     = 0 (0.0MB)
   free     = 26804224 (25.5625MB)
   0.0% used
concurrent mark-sweep generation:
   capacity = 2952790016 (2816.0MB)
   used     = 66930392 (63.829795837402344MB)
   free     = 2885859624 (2752.1702041625977MB)
   2.2666830908168447% used
Perm Generation:
   capacity = 45752320 (43.6328125MB)
   used     = 27404664 (26.13512420654297MB)
   free     = 18347656 (17.49768829345703MB)
   59.89786747426142% used

Ответ 1

По-видимому, существуют различные факторы, которые могут привести к тому, что MaxHeapFreeRatio не будет соблюдаться:

Ответ 2

Объем памяти, зарезервированный для операционной системы для кучи, определяется минимальной кучей и максимальной кучей, параметрами -Xms и -Xmx в командной строке java. Различные коэффициенты коллектора мусора и другие конфигурации являются внутренними по отношению к этому и не влияют на то, сколько всего используется JVM памяти, только как оно упорядочивает вещи в этой памяти.

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

Ответ 3

В JRE 1.7 вы можете использовать -XX:+UseG1GC -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15. Однако, чтобы получить сжатие памяти, вам все равно нужно явно вызвать GC, вызвав System.gc().

Ответ 4

Я использовал комбинацию -XX: + UseG1GC -XX: ParallelGCThreads = 15 -XX: MinHeapFreeRatio = 30 -XX: MaxHeapFreeRatio = 70 -verbosegc -XX: + PrintGCDetails -Dsun.rmi.dgc.client.gcInterval = 60000 -Dsun.rmi.dgc.server.gcInterval = 100000  и он сохранил мою системную сбой, используемая память переходит на 99,8%, а затем освобождается.

Спасибо: Шахид аббаси