Hi there!
While using this amazing library during a mass-failure event, we noticed how our service (which is continuously scanning the classpath using a new ClassGraph()....scan() invocation, to find file changes, was displaying a memory leak.
Upon looking at the histogram, and after being able to reproduce the issue in a controlled environment where I was able to get a heap dump, we noticed that the biggest offenders were the following (this was after a few days):
num #instances #bytes class name (module)
-------------------------------------------------------
1: 8973221 430714608 java.lang.ThreadGroup (java.base@17.0.15.0.101)
2: 8973220 287151232 [Ljava.lang.Thread; (java.base@17.0.15.0.101)
These thread groups, as it came out from the heap dump, were all called ClassGraph-thread-group and came from the newThread() method in SimpleThreadFactory
Those thread and groups seem to have a GC root of JNI Global which is preventing them from being GC'd.
The easy fix was to use an ad-hoc fixed thread pool, but I was wondering if I missed something in the docs or in the examples that would have prevented this issue.
Thank you!
Hi there!
While using this amazing library during a mass-failure event, we noticed how our service (which is continuously scanning the classpath using a
new ClassGraph()....scan()invocation, to find file changes, was displaying a memory leak.Upon looking at the histogram, and after being able to reproduce the issue in a controlled environment where I was able to get a heap dump, we noticed that the biggest offenders were the following (this was after a few days):
These thread groups, as it came out from the heap dump, were all called
ClassGraph-thread-groupand came from the newThread() method inSimpleThreadFactoryThose thread and groups seem to have a GC root of
JNI Globalwhich is preventing them from being GC'd.The easy fix was to use an ad-hoc fixed thread pool, but I was wondering if I missed something in the docs or in the examples that would have prevented this issue.
Thank you!