Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java OutOfMemoryError, but very few Live Objects seen in JFR?

I have some code that throws an OutOfMemoryError.

I set the JVM to dump on OOM and I opened the dump in Java Flight Recorder.

When inspecting the Live Objects in JFR, I see very few objects (less than 60).

How can I find out the largest object(s) being held in memory and noncollectable at the moment the OOM was triggered?

like image 257
Alex R Avatar asked Jun 27 '26 05:06

Alex R


2 Answers

Objects are sampled, so there is no way you can be sure to see the largest object before OOM.

That said, 60 samples are usually sufficient to find a memory leak, at least if the application has been running for some time and the leak is not negligible in size.

Samples that happens in the beginning are typically singletons and static objects that you have for the whole duration of application. Samples that happen at the end are typically short-lived objects that are to be garbage collected. In JMC you can click in "the middle" of the timeline on top to find memore leak candidates. Then you can look at stack trace and path to GC root and see if you see something suspicious.

You can also use the command line tool and do:

$ jfr print --events OldObjectSample --stack-depth 64 recording.jfr

It will list the samples in chronological order. It may be easier to see each sample than looking at an aggregate. The command line approach is described in detail here

like image 75
Kire Haglin Avatar answered Jun 29 '26 18:06

Kire Haglin


You can't do this in an automated way (like memory analyzer tools do it with heap dumps) due to the nature of data being collected.

It is totally fine that you can see only handful of objects. The reason is how low overhead sampling works - on every new TLAB allocation JFR steps in and takes a few objects from old TLAB. Therefore you don't get all objects recorded, only a representative sample of objects being allocated. This should be enough to give you a ratio of objects in heap. Also, all of the objects reported are live at the point of recording dump.

If you think that you get too little samples to come to a proper conclusion, it might be that your heap is small relative to TLAB size and you might want to reduce TLAB size. This is not advisable in production environment as improper TLAB setting can reduce application performance.

If you had "Memory Leak Detection" to "Object types + Allocation Stack Traces + Path to GC Root" set in the profiling configuration during record, you can trace where live objects go in code after being created and you can reconstruct representative dominator tree that way.

If you care about large objects meaning large themselves (and not retaining most of heap), you can find objects that are larger than TLAB by looking at "TLAB Allocations" page and look for "Total Allocations Outside TLAB" column. This data would be collected only if profiling configuration had "Memory Profiling" set to "Object Allocation and Promotion".

By profiling configuration I mean the file that you specify with settings option when you start recording with JFR. This file can be created using JMC application's "Flight Recording Template Manager".

like image 30
Roman Markunas Avatar answered Jun 29 '26 18:06

Roman Markunas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!