diff options
author | Joakim Erdfelt | 2016-02-04 18:03:45 +0000 |
---|---|---|
committer | Joakim Erdfelt | 2016-02-04 18:03:45 +0000 |
commit | cfe823a7d6edab044d4a1751dd3dfa2dda89c3e6 (patch) | |
tree | 398d3427419d00e51cde01d21ebe100d11e22d60 | |
parent | 980ab316cad2a95d2b4ac73882ceb2a3bb147b09 (diff) | |
download | org.eclipse.jetty.project-cfe823a7d6edab044d4a1751dd3dfa2dda89c3e6.tar.gz org.eclipse.jetty.project-cfe823a7d6edab044d4a1751dd3dfa2dda89c3e6.tar.xz org.eclipse.jetty.project-cfe823a7d6edab044d4a1751dd3dfa2dda89c3e6.zip |
487197 - Deflater/Inflater memory leak with WebSocket permessage-deflate extension
+ CompressExtension implementations are now part of the Jetty LifeCycle
+ Deflater and Inflater implementations are only instantiated when
needed.
+ CompressExtension.doStop() LifeCycle will call .end() on instantiated
Deflater and Inflater implementations
3 files changed, 42 insertions, 9 deletions
diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java index 58e8c90db6..f1abf1e49f 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/AbstractExtension.java @@ -23,7 +23,9 @@ import java.io.IOException; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.BatchMode; @@ -38,7 +40,7 @@ import org.eclipse.jetty.websocket.common.LogicalConnection; import org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope; @ManagedObject("Abstract Extension") -public abstract class AbstractExtension extends ContainerLifeCycle implements Extension +public abstract class AbstractExtension extends AbstractLifeCycle implements Dumpable, Extension { private final Logger log; private WebSocketPolicy policy; @@ -52,11 +54,15 @@ public abstract class AbstractExtension extends ContainerLifeCycle implements Ex { log = Log.getLogger(this.getClass()); } - + @Override + public String dump() + { + return ContainerLifeCycle.dump(this); + } + public void dump(Appendable out, String indent) throws IOException { - super.dump(out, indent); // incoming dumpWithHeading(out, indent, "incoming", this.nextIncoming); dumpWithHeading(out, indent, "outgoing", this.nextOutgoing); diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java index 720e98146b..2cde3a5ab3 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/ExtensionStack.java @@ -29,6 +29,7 @@ import org.eclipse.jetty.util.IteratingCallback; import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.component.LifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.websocket.api.BatchMode; @@ -89,6 +90,11 @@ public class ExtensionStack extends ContainerLifeCycle implements IncomingFrames Extension ext = exts.next(); ext.setNextOutgoingFrames(nextOutgoing); nextOutgoing = ext; + + if (ext instanceof LifeCycle) + { + addBean(ext,true); + } } // Connect incomings diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java index ac32ad6d72..f7325c73c3 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/extensions/compress/CompressExtension.java @@ -74,28 +74,34 @@ public abstract class CompressExtension extends AbstractExtension private final Queue<FrameEntry> entries = new ConcurrentArrayQueue<>(); private final IteratingCallback flusher = new Flusher(); - private final Deflater deflater; - private final Inflater inflater; + private Deflater deflaterImpl; + private Inflater inflaterImpl; protected AtomicInteger decompressCount = new AtomicInteger(0); private int tailDrop = TAIL_DROP_NEVER; private int rsvUse = RSV_USE_ALWAYS; protected CompressExtension() { - deflater = new Deflater(Deflater.DEFAULT_COMPRESSION,NOWRAP); - inflater = new Inflater(NOWRAP); tailDrop = getTailDropMode(); rsvUse = getRsvUseMode(); } public Deflater getDeflater() { - return deflater; + if (deflaterImpl == null) + { + deflaterImpl = new Deflater(Deflater.DEFAULT_COMPRESSION,NOWRAP); + } + return deflaterImpl; } public Inflater getInflater() { - return inflater; + if (inflaterImpl == null) + { + inflaterImpl = new Inflater(NOWRAP); + } + return inflaterImpl; } /** @@ -155,6 +161,8 @@ public abstract class CompressExtension extends AbstractExtension } byte[] output = new byte[DECOMPRESS_BUF_SIZE]; + Inflater inflater = getInflater(); + while(buf.hasRemaining() && inflater.needsInput()) { if (!supplyInput(inflater,buf)) @@ -346,6 +354,17 @@ public abstract class CompressExtension extends AbstractExtension } return true; } + + @Override + protected void doStop() throws Exception + { + LOG.info("doStop()"); + if(deflaterImpl != null) + deflaterImpl.end(); + if(inflaterImpl != null) + inflaterImpl.end(); + super.doStop(); + } @Override public String toString() @@ -429,6 +448,8 @@ public abstract class CompressExtension extends AbstractExtension LOG.debug("Compressing {}: {} bytes in {} bytes chunk",entry,remaining,outputLength); boolean needsCompress = true; + + Deflater deflater = getDeflater(); if (deflater.needsInput() && !supplyInput(deflater,data)) { |