首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOM使用320 x 16 320 DirectByteBuffer对象杀死JVM

OOM使用320 x 16 320 DirectByteBuffer对象杀死JVM
EN

Stack Overflow用户
提问于 2021-04-13 04:40:13
回答 2查看 3.1K关注 0票数 4

我在一个7.5GB的RAM服务器上运行了一个应用程序(没有交换),它使用的是args:

-Xmx3g -Xms3g -Xlog:gc -XX:+UseG1GC -XX:MaxGCPauseMillis=1000 -XX:MaxDirectMemorySize=500m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -Dio.netty.maxDirectMemory=0 -Djdk.nio.maxCachedBufferSize=104857

进程的RSS不断增加,而堆是90%的空,直到linux内存杀手采取行动为止。

做了堆大便:

SELECT db, db.capacity, classof(inbounds(db).get(0)).getName() FROM java.nio.DirectByteBuffer db WHERE classof(inbounds(db).get(0)).getName().startsWith("io.netty")

并从io.netty.buffer.PoolThreadCache$MemoryRegionCache$Entry中得到了320个使用capacity==16MB的DirectByteBuffer实例。

(我想并不是所有的“容量”都是实际分配的,因为它将超过5GB)

该应用程序没有直接使用Netty,但一些依赖项是: S3、Redisson、version -> 4.1.58。使用grpc-netty阴影的Google云监视(1.34.1)

我怎么能控制使用的内存量?

EN

回答 2

Stack Overflow用户

发布于 2021-04-13 06:50:24

Netty有几个java属性,您可以根据需要进行调整。

默认情况下,Netty在缓冲池分配器中使用直接内存分配。池分配器是强烈推荐的,因为它重用内存,无论直接与否。我建议不要更改默认的缓冲池分配器。

下面是在Java命令启动时设置的一些属性:

  • -Dio.netty.noPreferDirect=true (默认情况下是false):如果为真,将不使用池分配器中的直接内存,而是使用堆内存;请注意,由于直接内存是最快的,因此它可能会减慢一些,您需要使用-Xms -Xmx

为JVM分配更多的内存

  • -Dio.netty.maxDirectMemory=x (默认为-1):您可以更改此值

代码语言:javascript
复制
- If `<0`,  means Netty use twice Direct memory from JDK and don't use cleaner. default value
- If `0`, means Netty use the max JDK Direct ram and use Cleaner (**recommended**).
- If `>0`, means Netty use this max Direct, not related to max of JDK, and don't use cleaner.

因此,例如,如果您能够为Netty使用直接内存(而且更可取),但不超过1GB,则可以设置:

  • -Dio.netty.maxDirectMemory=0

如果不需要任何直接缓冲区,则可以设置:

  • -Dio.netty.noPreferDirect=true
  • -Dio.netty.maxDirectMemory=0

结束但并非最不重要的是,除了前面的设置之一:

如果使用直接内存,

  • -XX:MaxDirectMemorySize=500m可能太小,可能会将其增加为-XX:MaxDirectMemorySize=1024m或更多的
  • ,您可能会减少-Xmx3g -Xms3g (如-Xmx2g -Xms2g

)

票数 5
EN

Stack Overflow用户

发布于 2021-04-13 06:38:22

如果没有像您所做的那样导致OOM,则无法控制内存量。Netty池的行为不像Java和堆,即增加了一些工作的节流/频率,以便在指定的范围内使用资源(在特定情况下抛出OOM )。Netty内存池是为了模拟本地分配程序(如jemalloc )的行为而构建的,因此它的目的是保留应用程序所需的内存。因此,保留的直接内存取决于应用程序代码执行的分配压力(即未释放的未分配的分配数)。

相反,我建议接受它的特性,在预试/测试机器上准备一个有趣的测试负载,只需监视您感兴趣的应用程序的Netty直接内存使用情况。我想您已经配置了-Dio.netty.maxDirectMemory=0,以便使用JMX公开所使用的直接内存,但是Netty也可以公开它自己的度量标准(保存设置io.netty.maxDirectMemory),只需检查使用它的库是否负责通过JMX或使用任何度量框架公开。如果这些应用程序不公开它,则API相当容易使用,请参阅https://netty.io/4.1/api/io/netty/buffer/PooledByteBufAllocatorMetric.html

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67068818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档