Elia Rohana
Elia Rohana

Reputation: 326

spring boot 2 actuator jvm.gc.memory.allocated Metric

i'm using spring boot 2.2.5 and monitoring my application metrics via spring boot actuator and Grafana.

my application is packaged with Docker(OpenJdk11) and configured with 4GB of memory

i'm having long gc pauses that get around 1-2 seconds, and it is correlated with high jvm.gc.memory.allocated .

the jvm.gc.memory.allocated metrics sometimes gets to 30GB

can anyone explain the jvm.gc.memory.allocated metric ? what does it mean ?

Upvotes: 3

Views: 4302

Answers (1)

Eugene
Eugene

Reputation: 120848

This is a rather weird metric, if you ask me (in the sense that it is not trivial to grasp). Let's take it slow.

First of all it is generated by micrometer here and if you read it's description:

Incremented for an increase in the size of the young generation memory pool after one GC to before the next

it probably would make little sense to you too. I had to look at what the code that computes it, to understand what it does.

If you know some basic things about how a GC works and look at this code, things are rather simple, actually.

A generational garbage collector (like G1) divides the heap into regions (young and old). Allocations of new Objects happen in the young region (unless humongous, but I will not get into it), specifically in Eden space. Once a GC is triggered, Eden is cleared and allocations can happen again. This is rather simplified and not entirely correct (things are slightly different in case of major/mixed collections).

Now that this theory is in place, you can look at what isYoungGenPool is, from :

if (youngGenPoolName != null) {
      final long youngBefore = before.get(youngGenPoolName).getUsed();
      final long youngAfter = after.get(youngGenPoolName).getUsed();
      final long delta = youngBefore - youngGenSizeAfter.get();
      youngGenSizeAfter.set(youngAfter);
      if (delta > 0L) {
           allocatedBytes.increment(delta);
      }
}

Specifically, it is defined here:

... endsWith("Eden Space")

As such, this code takes a snapshot - of what Used Space was before and after a GC cycle in the Eden Space, computes a delta and adds all these deltas into a single value. This is what jvm.gc.memory.allocated is.


This sort of measures how much your application allocates during its lifetime, but only via young space. imho, you should carefully look at it since :

  • it does not track humongous allocations (there is a different metric for this)

  • it only works for generational garbage collectors (Shenandoah is not such a collector for example)

Upvotes: 8

Related Questions