Fix memory leak by adding the Http2StreamRemovalPolicy to the channel pipeline.

In benchmarks we would see grpc talking up tens of gigabytes of memory. A heap dump
revealed that streams would not get cleaned up and stick around in memory forever.
This commit is contained in:
Jakob Buchgraber 2015-04-06 17:53:34 -07:00
parent fcf1517054
commit 105964bfac
2 changed files with 6 additions and 4 deletions

View File

@ -160,7 +160,8 @@ public class Http2Negotiator {
/** /**
* Create a plaintext upgrade negotiation for HTTP/1.1 to HTTP/2. * Create a plaintext upgrade negotiation for HTTP/1.1 to HTTP/2.
*/ */
public static Negotiation plaintextUpgrade(final Http2ConnectionHandler handler) { public static Negotiation plaintextUpgrade(final ChannelHandler streamRemovalPolicy,
Http2ConnectionHandler handler) {
// Register the plaintext upgrader // Register the plaintext upgrader
Http2ClientUpgradeCodec upgradeCodec = new Http2ClientUpgradeCodec(handler); Http2ClientUpgradeCodec upgradeCodec = new Http2ClientUpgradeCodec(handler);
HttpClientCodec httpClientCodec = new HttpClientCodec(); HttpClientCodec httpClientCodec = new HttpClientCodec();
@ -170,6 +171,7 @@ public class Http2Negotiator {
final ChannelInitializer<Channel> initializer = new ChannelInitializer<Channel>() { final ChannelInitializer<Channel> initializer = new ChannelInitializer<Channel>() {
@Override @Override
public void initChannel(Channel ch) throws Exception { public void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(streamRemovalPolicy);
ch.pipeline().addLast(upgrader); ch.pipeline().addLast(upgrader);
ch.pipeline().addLast(completionHandler); ch.pipeline().addLast(completionHandler);
} }
@ -200,7 +202,7 @@ public class Http2Negotiator {
/** /**
* Create a "no-op" negotiation that simply assumes the protocol to already be negotiated. * Create a "no-op" negotiation that simply assumes the protocol to already be negotiated.
*/ */
public static Negotiation plaintext(final ChannelHandler handler) { public static Negotiation plaintext(final ChannelHandler... handlers) {
final ChannelInitializer<Channel> initializer = new ChannelInitializer<Channel>() { final ChannelInitializer<Channel> initializer = new ChannelInitializer<Channel>() {
@Override @Override
public void initChannel(Channel ch) throws Exception { public void initChannel(Channel ch) throws Exception {

View File

@ -137,11 +137,11 @@ class NettyClientTransport implements ClientTransport {
handler = newHandler(streamRemovalPolicy); handler = newHandler(streamRemovalPolicy);
switch (negotiationType) { switch (negotiationType) {
case PLAINTEXT: case PLAINTEXT:
negotiation = Http2Negotiator.plaintext(handler); negotiation = Http2Negotiator.plaintext(streamRemovalPolicy, handler);
ssl = false; ssl = false;
break; break;
case PLAINTEXT_UPGRADE: case PLAINTEXT_UPGRADE:
negotiation = Http2Negotiator.plaintextUpgrade(handler); negotiation = Http2Negotiator.plaintextUpgrade(streamRemovalPolicy, handler);
ssl = false; ssl = false;
break; break;
case TLS: case TLS: