From 9ff69f265dae8f0647fb9c204fda070eafe25613 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Wed, 13 Jun 2012 21:05:11 +0000
Subject: [PATCH] Fix OPENDJ-520: Worker threads are too greedy when caching memory used for encoding/decoding entries and protocol messages
---
opends/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriter.java | 70 +++++++++++++++++++++++-----------
1 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/opends/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriter.java b/opends/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriter.java
index 69ee24b..8ff76ef 100644
--- a/opends/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriter.java
+++ b/opends/src/server/org/opends/server/protocols/asn1/ASN1OutputStreamWriter.java
@@ -23,6 +23,7 @@
*
*
* Copyright 2006-2009 Sun Microsystems, Inc.
+ * Portions copyright 2012 ForgeRock AS.
*/
package org.opends.server.protocols.asn1;
@@ -48,22 +49,30 @@
private static final DebugTracer TRACER = getTracer();
private final OutputStream rootStream;
- private OutputStream out;
private final ArrayList<ByteSequenceOutputStream> streamStack;
+ private final int maxInternalBufferSize;
+ private OutputStream out;
private int stackDepth;
+
+
/**
* Creates a new ASN.1 output stream reader.
*
* @param stream
* The underlying output stream.
+ * @param maxInternalBufferSize
+ * The threshold capacity beyond which internal cached buffers used
+ * for encoding and decoding protocol messages will be trimmed after
+ * use.
*/
- ASN1OutputStreamWriter(OutputStream stream)
+ ASN1OutputStreamWriter(OutputStream stream, int maxInternalBufferSize)
{
this.out = stream;
this.rootStream = stream;
this.streamStack = new ArrayList<ByteSequenceOutputStream>();
this.stackDepth = -1;
+ this.maxInternalBufferSize = maxInternalBufferSize;
}
/**
@@ -470,14 +479,16 @@
// Make sure we have a cached sub-stream at this depth
if(stackDepth >= streamStack.size())
{
- ByteSequenceOutputStream subStream =
- new ByteSequenceOutputStream(new ByteStringBuilder());
+ ByteSequenceOutputStream subStream = new ByteSequenceOutputStream(
+ new ByteStringBuilder(), maxInternalBufferSize);
streamStack.add(subStream);
out = subStream;
}
else
{
- out = streamStack.get(stackDepth);
+ ByteSequenceOutputStream childStream = streamStack.get(stackDepth);
+ childStream.reset(); // Precaution.
+ out = childStream;
}
/*
if(debugEnabled())
@@ -535,29 +546,42 @@
}
/**
- * Closes this ASN.1 writer and the underlying outputstream. Any unfinished
- * sequences will be ended.
- *
- * @throws IOException if an error occurs while closing the stream.
+ * {@inheritDoc}
*/
- public void close() throws IOException {
- while(stackDepth >= 0)
+ public void close() throws IOException
+ {
+ try
+ {
+ flush();
+ }
+ finally
+ {
+ try
+ {
+ rootStream.close();
+ }
+ finally
+ {
+ // Reset for next usage in case where the root stream is reusable (e.g.
+ // ByteStringBuilder).
+ stackDepth = -1;
+ out = rootStream;
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public void flush() throws IOException
+ {
+ while (stackDepth >= 0)
{
writeEndSequence();
}
rootStream.flush();
-
- streamStack.clear();
- rootStream.close();
- }
-
- /**
- * Flushes the stream.
- *
- * @throws IOException If an I/O error occurs
- */
- public void flush() throws IOException {
- rootStream.flush();
}
/**
--
Gitblit v1.10.0