You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aurora.apache.org by se...@apache.org on 2016/02/14 23:34:49 UTC

aurora git commit: Always close Deflater/Inflater streams

Repository: aurora
Updated Branches:
  refs/heads/master 2b48f2216 -> c76cfcc5f


Always close Deflater/Inflater streams

Closing Deflater/Inflater streams explicitly frees their native memory instantly. Otherwise, the memory will only be freed once the object finalizer runs.

I got the idea from this article http://www.evanjones.ca/java-native-leak-bug.html. Unfortunately, we cannot use the Java close-with-resource feature, as `TTransport` in our current Thrift version does not implement `Closable`.

Reviewed at https://reviews.apache.org/r/43567/


Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/c76cfcc5
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/c76cfcc5
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/c76cfcc5

Branch: refs/heads/master
Commit: c76cfcc5f0bf9013f39593b1ac00cd44efc79c40
Parents: 2b48f22
Author: Stephan Erb <se...@apache.org>
Authored: Sun Feb 14 23:34:10 2016 +0100
Committer: Stephan Erb <st...@dev.static-void.de>
Committed: Sun Feb 14 23:34:10 2016 +0100

----------------------------------------------------------------------
 .../apache/aurora/codec/ThriftBinaryCodec.java  | 30 +++++++++++---------
 1 file changed, 17 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/c76cfcc5/src/main/java/org/apache/aurora/codec/ThriftBinaryCodec.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/codec/ThriftBinaryCodec.java b/src/main/java/org/apache/aurora/codec/ThriftBinaryCodec.java
index 6b65c0f..3c12532 100644
--- a/src/main/java/org/apache/aurora/codec/ThriftBinaryCodec.java
+++ b/src/main/java/org/apache/aurora/codec/ThriftBinaryCodec.java
@@ -145,24 +145,26 @@ public final class ThriftBinaryCodec {
   public static byte[] deflateNonNull(TBase<?, ?> tBase) throws CodingException {
     requireNonNull(tBase);
 
+    // NOTE: Buffering is needed here for performance.
+    // There are actually 2 buffers in play here - the BufferedOutputStream prevents thrift from
+    // causing a call to deflate() on every encoded primitive. The DeflaterOutputStream buffer
+    // allows the underlying Deflater to operate on a larger chunk at a time without stopping to
+    // copy the intermediate compressed output to outBytes.
+    // See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4986239
     ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
+    TTransport transport = new TIOStreamTransport(
+        new BufferedOutputStream(
+            new DeflaterOutputStream(outBytes, new Deflater(DEFLATE_LEVEL), DEFLATER_BUFFER_SIZE),
+            DEFLATER_BUFFER_SIZE));
     try {
-      // NOTE: Buffering is needed here for performance.
-      // There are actually 2 buffers in play here - the BufferedOutputStream prevents thrift from
-      // causing a call to deflate() on every encoded primitive. The DeflaterOutputStream buffer
-      // allows the underlying Deflater to operate on a larger chunk at a time without stopping to
-      // copy the intermediate compressed output to outBytes.
-      // See http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4986239
-      TTransport transport = new TIOStreamTransport(
-          new BufferedOutputStream(
-              new DeflaterOutputStream(outBytes, new Deflater(DEFLATE_LEVEL), DEFLATER_BUFFER_SIZE),
-              DEFLATER_BUFFER_SIZE));
       TProtocol protocol = PROTOCOL_FACTORY.getProtocol(transport);
       tBase.write(protocol);
-      transport.close();
+      transport.close(); // calls finish() on the underlying stream, completing the compression
       return outBytes.toByteArray();
     } catch (TException e) {
       throw new CodingException("Failed to serialize: " + tBase, e);
+    } finally {
+      transport.close();
     }
   }
 
@@ -181,14 +183,16 @@ public final class ThriftBinaryCodec {
     requireNonNull(buffer);
 
     T tBase = newInstance(clazz);
-    try {
-      TTransport transport = new TIOStreamTransport(
+    TTransport transport = new TIOStreamTransport(
           new InflaterInputStream(new ByteArrayInputStream(buffer)));
+    try {
       TProtocol protocol = PROTOCOL_FACTORY.getProtocol(transport);
       tBase.read(protocol);
       return tBase;
     } catch (TException e) {
       throw new CodingException("Failed to deserialize: " + e, e);
+    } finally {
+      transport.close();
     }
   }