Details
Description
During some memory leak analysis i noticed that one of my object which was expected to die was kept alive for longer than expected. The only reference to it was in ReusableParametrizedMessage
This object was pretty heavy and hold tens-hundreds of references to child object alive also.
I had to disable logging to test the leaks.
The side effect to this is:
- Holding the references longer than expected will move the memory from young generation to tenured generation where collection is more expensive and affect performance
- Debugging memory leaks just became harder.
ReusableParametrizedMessage should not hold references to objects beyond their intended lifetime
As you can see in this sample code
ReusableParameterizedMessage set(final String messagePattern, final Object p0) { params[0] = p0; init(messagePattern, 1, params); return this; } ReusableParameterizedMessage set(final String messagePattern, final Object p0, final Object p1) { params[0] = p0; params[1] = p1; init(messagePattern, 2, params); return this; }
If i call set(pattern,p0,p1) and then set(pattern, p0) ...then reference to p1 is kept alive until overriden by another set.
I don't have an understanding about log4j inner workings but for me the references should be kept only for the duration of the call to log.
I would be happy to be able to disable the mechanism. We are anyway running the software with INFO level and without logging the data plane so this optimization does not really bring much.
How about just setting the params to null after finishing the logging ?