Java 内存使用异常疑难解答
我正在尝试对需要越来越多内存的Java程序进行故障排除,直到它无法再分配,然后崩溃。
编辑有关该计划的更多信息。该程序是一个索引器,用于遍历数千个文档并将它们编入索引以进行搜索。这些文档从MongoDB读取,并在执行一些处理后写入MongoDB。在处理过程中,我使用的是RocksDB(来自Maven的rocksdb-jni版本5.13.4)。在GitHub的这个问题中,有一些提到RocksDB内存使用量不受控制地增长,但我不确定它是否相关。
使用 visualvm 监视进程的结果如下图所示:
但是在机器上运行显示完全不同的统计数据:htop
有几GB的内存存在差异,我无法追踪其来源。
程序使用以下 VM 参数启动:
jvm_args: -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=<port> -Djava.rmi.server.hostname=<hostname> -Xmx12G -XX:+UseStringDeduplication
系统有32GB的内存,没有交换。在这32 GB中,~10GB总是由tmpfs分区占用,~8GB由MongoDB占用,其余12GB分配给程序。编辑上面的 visualvm 屏幕截图显示了 20GB 的堆大小,因为它来自我通过的上一次运行;但是,无论我将12GB还是20GB分配给堆,行为都是相同的。如果我删除tmpfs分区,释放10 GB以上的内存,行为也不会改变:它只需要更长的时间,但最终它会耗尽内存。-Xmx20G
我不知道这种未在visualvm中显示但出现在其中的内存使用情况来自何处。我应该使用什么工具来了解正在发生的事情?该应用程序在远程服务器上运行,因此我想要一个仅在控制台中工作或可以配置为远程工作的工具,例如visualvm。htop