6

I have a java server task, which is hogging memory. For one I doubt it ever exceeded MinHeapFreeRatio, but that's speculation. It is more interesting that GC reduces the mature generation to roughly 2%, yet never reduces the allocated memory for the heap.

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
Mantriur
  • 986
  • 7
  • 20

4 Answers4

9

There are apparently various factors that can cause MaxHeapFreeRatio to not be honoured:

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    It should be noted that `-XX:ParallelGC` is the default GC on most machines (see http://stackoverflow.com/questions/33206313/default-garbage-collector-for-java-8) – Chin Dec 01 '16 at 15:54
  • >> The shrinkage only happens after a full GC << Does this mean that if you configure a specific new space it will never be shrunk? It would be good if I could target the old space to shrink and leave the others alone. In the normal case the old space of our app should not be increasing, but it is nice to have the overhead available. – jocull Nov 27 '19 at 16:15
  • 1
    If you use NewSize and MaxNewSize, my guess would be that they are immune from overall heap size shrinkage. – Stephen C Nov 27 '19 at 23:10
2

The amount of memory reserved from the operating system for the heap is determined by min heap and max heap, the parameters -Xms and -Xmx on the java command line. The various garbage collector ratios and other configurations are all internal to that and don't affect how much total memory JVM uses, just how it arranges things in that memory.

Commonly when people set up servers they set it so that -Xms and -Xmx are the same value, to avoid additional performance cost of resizing the heap and having to create contiguous memory space while the server is running if the heap needs to grow. This means that the amount of memory reserved from the operating system for heap will never shrink as a result of garbage collection, it just gets freed up to have new JVM data put in.

Affe
  • 47,174
  • 11
  • 83
  • 83
  • 1
    -Xms and -Xmx determine the possible min/max head size and yes, if you have a predictable application it might be an option to use these to take away the allocation decision from the VM. However, this is a server application and memory usage depends on the amount of clients, which always varies slightly, but might at times vary greatly, so dynamic memory allocation is great to leave unused memory to file buffers. MaxHeapFreeRatio SHOULD tell the VM when to return unused memory. Obviously that isn't happening as expected (by me :). – Mantriur Aug 27 '12 at 23:27
2

In JRE 1.7 you can use -XX:+UseG1GC -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=15 . However, to get memory shrinked you still need to invoke GC explicitly by calling System.gc().

0

I used combination -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 and it saved my system crashing used memory goes to 99.8% and then release.

Thanks: Shahid abbasi