-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible memory leak when using CompressionCodecs.DEFLATE #392
Comments
Thank you for this - fantastic analysis! This should be an easy fix. FWIW, the Line 71 will close the streams, and the |
I am happy to help. :) And yes, I agree: |
…ed GzipCompressionCodec and AbstractCompressionCodec to utilize consistent logic across compression algorithms. Resolves #392.
…ed GzipCompressionCodec and AbstractCompressionCodec to utilize consistent logic across compression algorithms. Resolves #392.
…ed GzipCompressionCodec and AbstractCompressionCodec to utilize consistent logic across compression algorithms. Resolves #392.
…ed GzipCompressionCodec and AbstractCompressionCodec to utilize consistent logic across compression algorithms. Resolves #392.
…ed GzipCompressionCodec and AbstractCompressionCodec to utilize consistent logic across compression algorithms. Resolves #392.
…ed GzipCompressionCodec and AbstractCompressionCodec to utilize consistent logic across compression algorithms. Resolves #392.
Prehistory
We are using jjwt 0.9.0 inside a Spring Boot application in a production environment, which is running in a Docker container. Here is some information about our environment:
Every second we create approximately 10-30 JWTs. Our web application crashes approximately every 24 hours because of OOM and Docker restarts it.
Problem description
After investigating a heap dump with Eclipse Memory Analyzer I found out that 28.71% of all memory is taken by 159,914 instances of java.lang.ref.Finalizer. After grouping all instances in heap dump by class and sorting by retained heap in descending order, I noticed that almost all instances of java.lang.ref.Finalizer refer to java.util.zip.Deflater and java.util.zip.Inflater objects.

Evidence
We don't use Deflater in our project, but we do use
compressWith(CompressionCodecs.DEFLATE)
, so I decided to disable JWT compression and see what will happen. After redeploying a fixed application version, memory consumption became pretty low and stable: it doesn't increase and even change during the application work, at least during several hours.Cause Investigation
I decided to investigate the JwtBuilder class and especially it's
compact()
method code. After some investigation, I've reached DeflateCompressionCodec and found that inside thebyte[] doCompress(byte[] payload)
method deflater'send
method was not called. Moreover, DeflaterOutputStream which is used to wrap deflater also doesn't call deflater'send
method. Let me explain why.As far as I can see, DeflaterOutputStream
close
method closes the deflater ifusesDefaultDeflater
flag istrue
. But this flag isfalse
by default and it becomestrue
only if you create a DeflaterOutputStream object using one of these constructors:DeflaterOutputStream(OutputStream out)
DeflaterOutputStream(OutputStream out, boolean syncFlush)
In our case
DeflaterOutputStream(OutputStream out, Deflater def, boolean syncFlush)
constructor is being used, sousesDefaultDeflater
remainsfalse
and the deflater remains open, which seems to lead to a memory leak. At least Oracle advices to callend
method in the Deflater documentation.Resolution
I suppose that you should either call deflater's
end
method inside thedoCompress
method or useDeflaterOutputStream with a default deflater.
Thank you for your attention.
P.S. Seems like Inflater has the same problem.
The text was updated successfully, but these errors were encountered: