Skip to content

Commit

Permalink
Reduce garbage with small jackson encoded data (Fixes #4977)
Browse files Browse the repository at this point in the history
  • Loading branch information
franz1981 authored and vietj committed Nov 29, 2023
1 parent bb20fd5 commit ea066cb
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
11 changes: 10 additions & 1 deletion src/main/java/io/vertx/core/buffer/impl/VertxHeapByteBuf.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,26 @@
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.UnpooledHeapByteBuf;
import io.netty.buffer.UnpooledUnsafeHeapByteBuf;

/**
* An un-releasable, un-pooled, un-instrumented heap {@code ByteBuf}.
*/
final class VertxHeapByteBuf extends UnpooledHeapByteBuf {

private static final byte[] EMPTY = new byte[0];

public VertxHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
super(alloc, initialCapacity, maxCapacity);
}

@Override
protected byte[] allocateArray(int initialCapacity) {
if (initialCapacity == 0) {
return EMPTY;
}
return super.allocateArray(initialCapacity);
}

@Override
public ByteBuf retain(int increment) {
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,20 @@
*/
final class VertxUnsafeHeapByteBuf extends UnpooledUnsafeHeapByteBuf {

private static final byte[] EMPTY = new byte[0];

public VertxUnsafeHeapByteBuf(ByteBufAllocator alloc, int initialCapacity, int maxCapacity) {
super(alloc, initialCapacity, maxCapacity);
}

@Override
protected byte[] allocateArray(int initialCapacity) {
if (initialCapacity == 0) {
return EMPTY;
}
return super.allocateArray(initialCapacity);
}

@Override
public ByteBuf retain(int increment) {
return this;
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/io/vertx/core/json/jackson/JacksonCodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.buffer.impl.BufferInternal;
import io.vertx.core.buffer.impl.VertxByteBufAllocator;
import io.vertx.core.json.DecodeException;
import io.vertx.core.json.EncodeException;
import io.vertx.core.json.JsonArray;
Expand Down Expand Up @@ -105,16 +105,19 @@ public String toString(Object object, boolean pretty) throws EncodeException {

@Override
public Buffer toBuffer(Object object, boolean pretty) throws EncodeException {
ByteBuf buf = Unpooled.buffer();
// these buffers are not pooled and not instrumented, which make them faster
// This can use 0 as initial capacity, because Jackson will flush the tmp encoded buffer in one go, on flush
// causing a single resize of the right final size
ByteBuf nettyBuffer = VertxByteBufAllocator.DEFAULT.heapBuffer(0, Integer.MAX_VALUE);
// There is no need to use a try with resources here as jackson
// is a well-behaved and always calls the closes all streams in the
// "finally" block bellow.
ByteBufOutputStream out = new ByteBufOutputStream(buf);
ByteBufOutputStream out = new ByteBufOutputStream(nettyBuffer);
JsonGenerator generator = createGenerator(out, pretty);
try {
encodeJson(object, generator);
generator.flush();
return BufferInternal.buffer(buf);
return BufferInternal.buffer(nettyBuffer);
} catch (IOException e) {
throw new EncodeException(e.getMessage(), e);
} finally {
Expand Down

0 comments on commit ea066cb

Please sign in to comment.