From 95230e01da5d9cf2447a9d09d4c42bf42eb7d479 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 17 Oct 2019 10:12:20 -0700 Subject: [PATCH] Try to reduce GC produced while writing headers (#9682) Motivation: bbc34d0eda38efb4a6364561e9ac1d2319682694 introduced correct handling of "in process" setup of streams but there is some room for improvements. Often the writeHeaders(...) is completed directly which means there is not need to create the extra listener object. Modifications: - Only create the listener if we really need too. Result: Less GC --- .../handler/codec/http2/Http2FrameCodec.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java index 6a2f37832c..41a87f9074 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodec.java @@ -159,12 +159,6 @@ public class Http2FrameCodec extends Http2ConnectionHandler { private int numBufferedStreams; private final IntObjectMap frameStreamToInitializeMap = new IntObjectHashMap(8); - private final ChannelFutureListener bufferedStreamsListener = new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture future) { - numBufferedStreams--; - } - }; Http2FrameCodec(Http2ConnectionEncoder encoder, Http2ConnectionDecoder decoder, Http2Settings initialSettings, boolean decoupleCloseAndGoAway) { @@ -420,26 +414,33 @@ public class Http2FrameCodec extends Http2ConnectionHandler { // We should not re-use ids. assert old == null; - // Clean up the stream being initialized if writing the headers fails. - promise.addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture channelFuture) { - if (!channelFuture.isSuccess()) { - frameStreamToInitializeMap.remove(streamId); - } - } - }); - encoder().writeHeaders(ctx, streamId, headersFrame.headers(), headersFrame.padding(), headersFrame.isEndStream(), promise); if (!promise.isDone()) { numBufferedStreams++; - promise.addListener(bufferedStreamsListener); + // Clean up the stream being initialized if writing the headers fails and also + // decrement the number of buffered streams. + promise.addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture channelFuture) { + numBufferedStreams--; + + handleHeaderFuture(channelFuture, streamId); + } + }); + } else { + handleHeaderFuture(promise, streamId); } } } + private void handleHeaderFuture(ChannelFuture channelFuture, int streamId) { + if (!channelFuture.isSuccess()) { + frameStreamToInitializeMap.remove(streamId); + } + } + private void onStreamActive0(Http2Stream stream) { if (stream.id() != Http2CodecUtil.HTTP_UPGRADE_STREAM_ID && connection().local().isValidStreamId(stream.id())) {