Java 进程的内存无限增长,但 MemoryMXBean 报告了稳定的堆和非堆大小
我正在与一个团队合作开发在1GB Linux目标系统上运行的Java GUI应用程序。
我们有一个问题,我们的java进程使用的内存无限增长,直到Linux最终杀死Java进程。
我们的堆记忆是健康和稳定的。(我们已经广泛分析了我们的堆)我们还使用 MemoryMXBean 来监视应用程序的非堆内存使用情况,因为我们认为问题可能就在那里。但是,我们看到的是,报告的堆大小 + 报告的非堆大小保持稳定。
下面是一个示例,说明在具有 1GB RAM 的目标系统上运行应用程序时,这些数字可能看起来如何(MemoryMXBean 报告的堆和非堆,使用 Linux 的 top 命令(驻留内存)监视 Java 进程使用的总内存):
启动时:
- 已提交 200 MB 堆
- 40 MB 非堆已提交
- Java 进程使用的 320 MB
1天后:
- 已提交 200 MB 堆
- 40 MB 非堆已提交
- Java 进程使用的 360 MB
2天后:
- 已提交 200 MB 堆
- 40 MB 非堆已提交
- Java 进程使用的 400 MB
上面的数字只是我们系统性能的“更清晰”的表示,但它们相当准确且接近现实。如您所见,趋势很明显。运行应用程序几周后,由于系统内存不足,Linux系统开始出现问题。事情开始放缓。再过几个小时,Java进程就会被杀死。
经过几个月的分析并试图理解这一点,我们仍然不知所措。我觉得很难找到有关此问题的信息,因为大多数讨论最终都会解释堆或其他非堆内存池。(如元空间等)
我的问题如下:
如果分解它,Java进程使用的内存包括什么?(除了堆和非堆内存池)
还有哪些其他潜在的内存泄漏源?(本机代码?JVM 开销?一般来说,哪些是最有可能的罪魁祸首?
如何监视/分析此内存?堆+非堆之外的所有内容目前对我们来说都是一个黑匣子。
任何帮助将不胜感激。