Hello!
I've been recently looking at some Java Flight Recordings and noticed a lot of JVM churn related to the Encoder.
|
/** |
|
* Encode an event as bytes. |
|
* |
|
* @param event |
|
*/ |
|
byte[] encode(E event); |
I have a custom Encoder that looks something like this:
public byte[] encode(E event) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
write(event, baos)
return baos.toByteArray();
}
And what I find is that we spend a lot of heap churn on the final call of .toByteArray() because it must make a copy of the data for every call to encode. Ideally, I could instead do something like:
public ByteBuffer encode(E event) {
// A simple subclass to get access to the protected 'buf' and 'count' fields
class ExposedBAOS extends ByteArrayOutputStream {
ByteBuffer getBuffer() {
return ByteBuffer.wrap(this.buf, 0, this.count);
}
}
final ExposedBAOS baos = new ExposedBAOS();
write(event, baos);
return baos.getBuffer();
}
... and avoid that altogether. I think this could be achieved with:
/**
* Encodes an event into a ByteBuffer.
* Default implementation wraps the result of encode(E event).
*/
default ByteBuffer encodeBuffer(E event) {
byte[] encoded = encode(event);
return (encoded != null) ? ByteBuffer.wrap(encoded) : null;
}
/**
* Encode an event as bytes.
*/
byte[] encode(E event);
Then update the callers to use the encodeBuffer method instead.
Hello!
I've been recently looking at some Java Flight Recordings and noticed a lot of JVM churn related to the Encoder.
logback/logback-core/src/main/java/ch/qos/logback/core/encoder/Encoder.java
Lines 39 to 44 in 420d67c
I have a custom Encoder that looks something like this:
And what I find is that we spend a lot of heap churn on the final call of
.toByteArray()because it must make a copy of the data for every call to encode. Ideally, I could instead do something like:... and avoid that altogether. I think this could be achieved with:
Then update the callers to use the
encodeBuffermethod instead.