Description
I ran into a problem recently where, if I created and used a lot of Parser
objects in a single thread, my application would OOM. Looking at the heap dump, I saw that that thread had thousands of inheritable thread locals, each of which had a DynamicVariable
that held a reference to a Parser$Failure
object, keeping my parser alive.
This DynamicVariable
was introduced by the fix in #4929, specifically scala/scala@dce6b34
I'm not familiar with DynamicVariable
so I don't know if the behavior I'm seeing is a bug in DynamicVariable
or a bug in how the parser libraries use DynamicVariable
- all I know is that, in this instance, they're combining to keep objects alive in a way that the garbage collector apparently can't see through.
I'm attaching a file to reproduce it; compile the file, then do
JAVA_OPTS="-verbose:gc -Xmx256m -Xms64m -XX:+UseCompressedOops -XX:+HeapDumpOnOutOfMemoryError" scala ParserLoop
and you'll have a heap dump in short order.