我的应用程序运行在一个docker容器中,它使用scala并使用“OpenJDK 64位服务器VM(build 25.102-b14,mixed mode)",其Xmx设置为16 GB,容器内存限制为24 Gb,运行一段时间后容器被杀死:
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
但是我找不到任何“java.lang.OutOfMemoryError:Java堆空间”错误在日志中,甚至没有一次在过去2周内在所有48个节点。所以这不太可能是一个普通的堆OOM。
dmesg输出:
$ dmesg -l err,crit,alert,emerg
STDIN is not a terminal
[1647254.978515] Memory cgroup out of memory: Kill process 10924 (java) score 1652 or sacrifice child
[1647254.989138] Killed process 10924 (java) total-vm:34187148kB, anon-rss:24853120kB, file-rss:23904kB
[1655749.664871] Memory cgroup out of memory: Kill process 1969 (java) score 1652 or sacrifice child
[1655749.675513] Killed process 1969 (java) total-vm:35201940kB, anon-rss:24856624kB, file-rss:24120kB
[1655749.987605] Memory cgroup out of memory: Kill process 2799 (java) score 1656 or sacrifice child
然后我运行JCMD多次,然后它再次被杀死,数据如下所示:本机内存跟踪:
合计:保留= 25505339 KB,提交= 25140947 KB- Java堆(保留= 16777216 KB,提交= 16777216 KB)(mmap:保留= 16777216 KB,提交= 16777216 KB)
- 类(保留= 247996 KB,提交= 93500 KB)(类#14539)(malloc= 2236 KB #29794)(mmap:保留= 245760 KB,提交= 91264 KB)
- 线程(保留= 1013160 KB,提交= 1013160 KB)(线程#1902)(堆栈:保留= 1003956 KB,提交= 1003956 KB)(malloc= 6240 KB #9523)(竞技场= 2964 KB #3803)
- 代码(保留= 263255 KB,提交= 86131 KB)(malloc= 13655 KB #20964)(mmap:保留= 249600 KB,提交= 72476 KB)
- GC(保留= 776174 KB,提交= 776174 KB)(malloc= 120814 KB #164310)(mmap:保留= 655360 KB,提交= 655360 KB)
- 缓存器(保留= 812 KB,提交= 812 KB)(malloc= 681 KB #1823)(竞技场= 131 KB #3)
- 内部(保留= 6366260 KB,提交= 6366256 KB)(malloc= 6366256 KB #178778)(mmap:保留=4KB,提交= 0 KB)
- 符号(保留= 18391 KB,提交= 18391 KB)(malloc= 16242 KB #153138)(竞技场= 2150 KB #1)
- 本机内存跟踪(保留= 9002 KB,提交= 9002 KB)(malloc= 186 KB #2000)(跟踪开销= 8816 KB)
- 竞技场块(保留= 273 KB,提交= 273 KB)(malloc= 273 KB)
- 未知(保留= 32800 KB,提交= 32 KB)(mmap:保留= 32800 KB,提交= 32 KB)
我注意到的一件事是这个部分:内部(保留= 6366260 KB,提交= 6366256 KB)
它不断增长,导致总内存使用量超过24 GB的限制。
以前有人见过类似的问题吗?有谁知道什么是内部内存吗,还有它不断增长而不释放内存的原因是什么?
4条答案
按热度按时间vsikbqxv1#
最近我们的应用程序遇到了同样的问题。在我们的例子中,我们使用netty,netty分配直接内存,当存在许多io连接时,java Native Memory Tracking中的内部内存会增加。
最后,我们使用两个参数来限制本机内存。
ujv3wf0j2#
这不是对你问题的回答,这只是一个解决方案。
我在Java版本“1.8.0_45”上运行JRuby的Docker容器中观察到了同样的问题。解决方案是显式调用垃圾收集。我完全不知道,为什么这工作,但在GC内部Java内存返回到8MB。
juzqafwq3#
您是否配置了
-XX:+DisableExplicitGC
?如果“是”,请删除。
如果配置了 no“
-XX:+DisableExplicitGC
“,通过JConsole触发全GC后的情况如何cyej8jka4#
我想你可能遇到了我在这里回答的问题:Java堆转储:如何找到占用内存1的对象/类。io.netty.buffer.ByteBufUtil 2. byte[]数组
如果你运行在一个有大量内核的节点上,你可能需要设置环境变量
MALLOC_ARENA_MAX
来控制本机内存的分配方式。