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();
}
}