Skip to content

Huge Off-heap memory used by java.nio.DirectByteBuffers #5583

@dmks

Description

@dmks

What version of gRPC are you using?

io.grpc:grpc-netty:1.20.0
io.grpc:grpc-stub:1.20.0
io.netty:netty-transport-native-epoll:4.1.34.Final:linux-x86_64
group: 'com.google.flatbuffers', name: 'flatbuffers-java', version: '1.10.0'
group: 'com.google.flatbuffers', name: 'flatbuffers-java-grpc', version: '1.10.0'

What did you expect to see?

No memory leak

Problem:

When I run stress tests with my grpc-java server on amazon linux 2, I saw huge process memory usage, but It was not heap memory or Metaspace (they are pretty small). so I took heap dump and use jxray to generate the report, I saw huge off-heap memory usage.

Here is the screenshot:
image

However, the server is running perfectly ok on my Mac pro with the same code.
And here is my code to start grpc server:
`ThreadFactory bossTF = new DefaultThreadFactory("boss-netty-", true /*daemon */);
ThreadFactory workerTF = new DefaultThreadFactory("worker-netty-", true /*daemon */);
final EventLoopGroup boss;
final EventLoopGroup worker;
final Class<? extends ServerChannel> channelType;

switch (transport) {
  case "nio": {
    boss = new NioEventLoopGroup(1, bossTF);
    worker = new NioEventLoopGroup(0, workerTF);
    channelType = NioServerSocketChannel.class;
    break;
  }
  case "epoll": {
    try {
      // These classes are only available on linux.
      Class<?> groupClass = Class.forName("io.netty.channel.epoll.EpollEventLoopGroup");
      @SuppressWarnings("unchecked")
      Class<? extends ServerChannel> channelClass = (Class<? extends ServerChannel>)
          Class.forName("io.netty.channel.epoll.EpollServerSocketChannel");
      boss =
          (EventLoopGroup)
              (groupClass
                  .getConstructor(int.class, ThreadFactory.class)
                  .newInstance(1, bossTF));
      worker =
          (EventLoopGroup)
              (groupClass
                  .getConstructor(int.class, ThreadFactory.class)
                  .newInstance(0, workerTF));
      channelType = channelClass;
      break;
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
  default: {
    // Should never get here.
    throw new IllegalArgumentException("Unsupported transport: " + transport);
  }
}

server = NettyServerBuilder.forPort(port)
    .bossEventLoopGroup(boss)
    .workerEventLoopGroup(worker)
    .channelType(channelType)
    .addService(engine)
    .build()
    .start();

logger.info("Server started, listening on " + port);

`

Thanks

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions