From ba11879c9f8a2d8aae308d83be9f240606ab0d32 Mon Sep 17 00:00:00 2001 From: Scott Mitchell Date: Fri, 11 Sep 2015 09:12:22 -0700 Subject: [PATCH] HTTP/2 codec heap buffer usage Motivation: The HTTP/2 codec has a few static buffers sent over the network which are allocated on the heap. This results in a copy operation when the buffer is sent out on the network. Modifications: - Ensure these static buffers are allocated using direct memory. Result: No copy operation necessary when writing static buffers to network. --- .../handler/codec/http2/Http2CodecUtil.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java index 1567d2a2d3..107b803d0b 100644 --- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java +++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2CodecUtil.java @@ -15,8 +15,6 @@ package io.netty.handler.codec.http2; -import static io.netty.util.CharsetUtil.UTF_8; - import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; @@ -27,14 +25,15 @@ import io.netty.channel.DefaultChannelPromise; import io.netty.handler.ssl.ApplicationProtocolNames; import io.netty.util.concurrent.EventExecutor; +import static io.netty.buffer.Unpooled.directBuffer; +import static io.netty.buffer.Unpooled.unmodifiableBuffer; +import static io.netty.buffer.Unpooled.unreleasableBuffer; +import static io.netty.util.CharsetUtil.UTF_8; + /** * Constants and utility method used for encoding/decoding HTTP2 frames. */ public final class Http2CodecUtil { - - private static final byte[] CONNECTION_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(UTF_8); - private static final byte[] EMPTY_PING = new byte[8]; - public static final int CONNECTION_STREAM_ID = 0; public static final int HTTP_UPGRADE_STREAM_ID = 1; public static final String HTTP_UPGRADE_SETTINGS_HEADER = "HTTP2-Settings"; @@ -52,6 +51,11 @@ public final class Http2CodecUtil { public static final short MAX_WEIGHT = 256; public static final short MIN_WEIGHT = 1; + private static final ByteBuf CONNECTION_PREFACE = unmodifiableBuffer( + unreleasableBuffer(directBuffer(24).writeBytes("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n".getBytes(UTF_8)))); + private static final ByteBuf EMPTY_PING = unmodifiableBuffer( + unreleasableBuffer(directBuffer(PING_FRAME_PAYLOAD_LENGTH).writeZero(PING_FRAME_PAYLOAD_LENGTH))); + private static final int MAX_PADDING_LENGTH_LENGTH = 1; public static final int DATA_FRAME_HEADER_LENGTH = FRAME_HEADER_LENGTH + MAX_PADDING_LENGTH_LENGTH; public static final int HEADERS_FRAME_HEADER_LENGTH = @@ -109,7 +113,7 @@ public final class Http2CodecUtil { */ public static ByteBuf connectionPrefaceBuf() { // Return a duplicate so that modifications to the reader index will not affect the original buffer. - return Unpooled.wrappedBuffer(CONNECTION_PREFACE); + return CONNECTION_PREFACE.duplicate().retain(); } /** @@ -117,7 +121,7 @@ public final class Http2CodecUtil { */ public static ByteBuf emptyPingBuf() { // Return a duplicate so that modifications to the reader index will not affect the original buffer. - return Unpooled.wrappedBuffer(EMPTY_PING); + return EMPTY_PING.duplicate().retain(); } /**