InitiatingHeapOccupancyPercent is set to 40 yet old gen memory going beyond 60 percent in G1GC
Asked Answered
R

1

8

I am trying to solve a problem where the heap memory is going beyond 90 percent in my java service.

Below is the heap configuration I am using,

-Xms6144m \
                -Xmx6144m \
                -verbose:gc \
               -XX:G1HeapRegionSize=2097152 \
               -XX:+PrintGC \
               -XX:+PrintFlagsFinal \
               -XX:InitiatingHeapOccupancyPercent=40 \
               -XX:NewRatio=2 \
               -XX:+PrintGCDetails \
               -XX:+PrintGCDateStamps \
               -XX:+PrintAdaptiveSizePolicy \
               -XX:+PrintTenuringDistribution \
               -XX:+UseGCLogFileRotation \
               -XX:NumberOfGCLogFiles=10 \
               -XX:GCLogFileSize=50M \
    -XX:+UnlockExperimentalVMOptions \
  -XX:+UseG1GC -XX:+UseStringDeduplication \
  -XX:+UseCGroupMemoryLimitForHeap \
  -XX:+ParallelRefProcEnabled
  -XX:+OptimizeStringConcat
  -XX:MaxRAMFraction=2 \
  -XshowSettings:vm

The problem is my old gen is gradually getting filled up and over the time the lower point to which the heap is going after GC is increasing, my graph looks something like this :

enter image description here

Can you suggest if my heap params are correct and are they conflicting in the way they are configured or how can I reduce the max heap getting used?

Rephrase answered 27/4, 2020 at 10:21 Comment(0)
A
3

G1GC is mainly designed for one thing, keeping your application responsive by:

trying to avoid that garbage collection of the "old gen" (the tenured objects that the application has hold on to for some time, like from a user session, cache, or some kind of memory leak) must be done in a single classic FullGC where your application is frozen while the entire heap has to be cleaned (which depending on the number of objects may take a long time, like several seconds. Read all about it here, one quote from it:

The goal is to reclaim as much heap space as possible (starting with those regions that contain the most reclaimable space) while attempting to not exceed the pause time goal

The 40% you set for the: InitiatingHeapOccupancyPercent relate to the (entire) heap occupancy and denote when to start a concurrent GC cycle (this should be visible in the logs, if not see: this related question ). GCs that trigger a concurrent GC cycle based on the occupancy of the entire heap and not just one of the generations (so not just Old Gen), including G1, use this option. A value of 0 denotes 'do constant GC cycles'. The default value is 45. (Adapted from: Oracle® Communications WebRTC Session Controller System Administrator's Guide )

So it is possible that:

  1. The GC cycle is initiated at 40% heap occupancy but before it is finished you reach a much higher level (like 90%), which may be entirely fine as long as your application is working
  2. You have some kind of memory leak (but that is hard to tell from the graph without knowing the application and how long it is running or see how it plays out after a longer time)
  3. There may be some other problems but it is impossible to tell without having the garbage collection logs to analyse, but you may want to refer to: Monica Beckwith's article on G1GC e.g. the part on Evacuation Failure

If you really want your application to use less memory (maybe at the price of some loss in performance/throughput) you could lower the MaxHeapSize (but you should use either one of: MaxRAMFraction or MaxHeapSize (XmX), not both).

Or depending on your application and performance requirements consider going for an entirely different JVM/Garbage Collector like:

A1 answered 9/5, 2020 at 7:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.