【问题标题】:GRPC Java - Prevent Memory LeaksGRPC Java - 防止内存泄漏
【发布时间】:2020-04-19 14:22:10
【问题描述】:

我试图阻止 GRPC 每个通道使用多个线程。为此,我使用以下代码设置了一个单线程执行器:

for (int i = 0; i < 3 * numFaults + 1; i++) {
            //One thread for each channel
            ManagedChannel channel = NettyChannelBuilder
                    .forAddress(host, port + i + 1)
                    .usePlaintext()
                    .executor(Executors.newSingleThreadExecutor())
                    .build();

然后我为每个通道创建一个异步存根。

但是,这似乎不起作用,因为我的程序中仍然产生太多线程,最终内存不足。

我应该将执行程序传递给存根吗?或者有什么根本性的错误。

提前致谢

【问题讨论】:

  • “每个通道使用多个线程”但每个通道只有一个线程执行器。
  • 是的,但是当我看到我机器上的线程使用情况时,我发现它仍在产生许多线程

标签: java multithreading grpc grpc-java


【解决方案1】:

额外产生的线程可能是 EventLoop 线程(默认情况下它最多可以创建 # 个核心线程)。在 NettyChannelBuilder 中有一个提供 EventLoopGroup 的选项。要使用此 API,您还需要设置 ChannelType。 EventLoopGroupChannel 类型来自 netty 如果您有兴趣,请参阅链接的 javadoc 了解更多详细信息。

如果在 linux 上,你可以使用 Epoll,否则使用 NIO 是当前的 gRPC 行为。下面的例子是使用 NIO。 所有网络事件都发生在事件循环线程上,因此使用较少的线程会显着影响整体性能(取决于通道的使用方式)。也可以考虑使用directExecutor,为EventLoopGroup分配更多线程。

NioEventLoopGroup sharedEventLoopGroup = new NioEventLoopGroup(numThread);
ManagedChannel channel = NettyChannelBuilder
    .forAddress(host, port + i + 1)
    .usePlaintext()
    .channelType(NioSocketChannel.class)
    .eventLoopGroup(sharedEventLoopGroup)
    .executor(Executors.newSingleThreadExecutor())
    .build();

【讨论】:

  • 忘了提一下,除非线程太多,否则很少会看到 #threads 导致内存不足。如果您的内存不足,请分析堆转储以查看其中的内容。这可能是由于泄漏,也可能不是。另外,请修改标题,因为这不是内存泄漏问题。
猜你喜欢
  • 2010-09-21
  • 2015-02-05
  • 1970-01-01
  • 2016-07-10
  • 2010-12-20
  • 2011-12-05
相关资源
最近更新 更多