<div dir="ltr"><div><div>Hi,</div><br></div>After switching our Jetty based server application from JDK 18 to JDK 20  I have noticed an increase in heap memory usage when using the G1 garbage collector (measured by MemoryMXBean.getHeapMemoryUsage().getUsed()). Previously a steady memory usage line on the JVM metrics dashboard started going up towards the maximum heap size.<br><br><div>I conducted a head dump analysis after several days of up-time and found out that the `jdk.internal.vm.ThreadContainers` class [1] is the biggest garbage collector root. The class static field `ThreadContainers.CONTAINER_REGISTRY contained a set of weakly referenced instances of `ThreadContainer`, the number of items in the set was growing regardless of the garbage collection cycles. <br><br>I have been observing this behavior on both Temurin and Corretto latest JDK 20 distributions (on Corretto though it took longer time to notice)<br></div><div><br></div><div>When I looked closely at the ThreadContainers source code, I noticed a private static`ThreadContainers.QUEUE` field intended to track and remove references eligible for garbage collection. The field contains an instance of the `ReferenceQueue` class which is only used in the `expungeStaleEntries` method and is not actually being populated. <br><br>I guess the idea was that `QUEUE` should have been passed as a second parameter to the `WeakReference` constructor in the `registerContainer` method, so the reference queue would properly register every new `ThreadContainer` instance.<br><br></div><div>Can someone please check this out?<br></div><div><br></div><div>Best regards,<br></div><div>Alexey<br></div><div>---<br>[1] <a href="https://github.com/openjdk/jdk/blob/f9a785e855287ff6746ac8dc8f8f2e2f90c5be07/src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java" target="_blank">https://github.com/openjdk/jdk/blob/f9a785e855287ff6746ac8dc8f8f2e2f90c5be07/src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java</a></div></div>