JMC Automated Analysis - App uses ~14 GB of Memory?

142 views Asked by At

I am very new to Java Profiling and JMC, so I am struggling to make sense of the data:

enter image description here

This is a simple Spring Azure Function running on my 16GB system.

The JFR was collected as a continuous recording, dumped after hardly 1 min of app startup.

What am I missing here?

PC information:

OS: Windows 11 x64
Processor   11th Gen Intel(R) Core(TM) i5-1145G7 @ 2.60GHz   2.61 GHz
Installed RAM   16.0 GB (15.7 GB usable)
System type 64-bit operating system, x64-based processor

No Docker involved.

2

There are 2 answers

0
Juraj Martinka On BEST ANSWER

The Memory usage report you showed is about your whole system including other processes. It does not say how much your app has consumed. It is perfectly normal for a system running many different processes. The OS also includes various caches, notably page cache.

To get better overview of memory consumed by your application, click on Memory in the left navigation bar: enter image description here

2
Simone Gianni On

The JVM will use as much RAM as possible (based on java version, the system it is running on, settings etc..), but it does not necessarily mean there is a problem or a memory leak.

Quite often, if you restrict the JVM to a lower amount of RAM, everything will still work fine, simply the garbage collection will run more often.

Try running it again with a much lower heap limit, using java -Xms6g (limit on 6 gigabytes) or similar switch, and see if it crashes or not .. it will probably not.

Restricting the maximum RAM available to the JVM and then running the application under some load is the best way I've found to determine the real minimum RAM need of a java piece of software .. once you determine that, multiply by 2 or 3 to stay safe and that's your' required RAM.

To explain what's going on in very simple terms, the JVM has a maximum amount of heap RAM it can use. When a request to allocate a new instance arrives (that is, any new instruction), it will just take some RAM so that the execution does not slow down. Once that instance is not used anymore (this part is pretty complex, but in general, when there are no active pointers to a given instance), that amount of RAM is marked as garbage ... but it will still be used.

Then, from time to time, the JVM will start a round of garbage collection. The garbage collector will take all these garbage RAM, and actually "free" it.

Now, this does not (necessarily) mean that the "freed" RAM is given back to the OS for other uses; the JVM will keep the RAM for itself, use it for other instances, and the cycle repeats.

This means the JVM will almost always run at 100% of the maximum allowed heap space, even if it could run the program correctly with less (even much less, even an order of magnitude less) RAM consumption.

The full story is much more complicated .. the heap is segmented in different generations, different generations use different garbage collection algorithms, the heap is compacted, there are other RAM consumers like stacks and static data etc..