Java 内存使用异常疑难解答

2022-09-04 23:22:13

我正在尝试对需要越来越多内存的Java程序进行故障排除,直到它无法再分配,然后崩溃。

编辑有关该计划的更多信息。该程序是一个索引器,用于遍历数千个文档并将它们编入索引以进行搜索。这些文档从MongoDB读取,并在执行一些处理后写入MongoDB。在处理过程中,我使用的是RocksDB(来自Maven的rocksdb-jni版本5.13.4)。在GitHub的这个问题中,有一些提到RocksDB内存使用量不受控制地增长,但我不确定它是否相关。

使用 visualvm 监视进程的结果如下图所示:

Memory usage on visualvm

但是在机器上运行显示完全不同的统计数据:htop

htop stats

有几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


答案 1

我总是使用JProfiler,但我听说jetbrains有一个很好的,两者都可以远程连接。

如果可能的话,我会尝试创建一个(本地)设置,您可以在其中自由测试它。

  • 在RocksDB中提到了几种可能的解决方案,它们有效吗?
  • RocksDB似乎需要一些配置,你们是怎么配置的?
  • 我不熟悉RocksDB,但我看到有一些索引和缓存正在进行中。您正在处理多少数据,您有哪些索引/缓存配置?你确定这应该适合记忆吗?
  • 据我所知,内存不匹配是因为大多数人默认情况下没有显示jni用法。有一些标志可以改进此本机记忆跟踪。我不记得这是否也会将它们添加到您的visualvm概述中。

karbos-538我刚刚注意到这是一个相当古老的问题,我希望这个应用程序现在已经工作了。问题的哪一部分仍然与你相关?


答案 2

推荐