如何监控 Java 内存使用情况?

我们有一个在Jboss上运行的j2ee应用程序,我们希望监视它的内存使用情况。目前我们使用以下代码

    System.gc();
    Runtime rt = Runtime.getRuntime();
    long usedMB = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024;
    logger.information(this, "memory usage" + usedMB);

此代码工作正常。这意味着它显示了与现实相对应的记忆曲线。当我们从数据库创建一个大的xml文件时,曲线上升,提取完成后,曲线下降。

alt text

一位顾问告诉我们,显式调用gc()是错误的,“让jvm决定何时运行gc”。基本上,他的论点与这里讨论的论点相同。但我仍然不明白:

  • 我怎样才能有我的内存使用曲线?
  • 显式 gc() 有什么问题?我不关心显式gc()可能发生的小性能问题,我估计在1-3%中。我需要的是内存和线程监视器,这有助于我在客户现场分析我们的系统。

答案 1

如果你想真正了解虚拟机内存中发生了什么,你应该使用像VisualVM这样的好工具。这是自由软件,这是了解正在发生的事情的好方法。

显式调用没有什么是真正“错误”的。但是,请记住,当您调用时,您是在“建议”垃圾回收器运行。无法保证它会在您运行该命令的确切时间运行。gc()gc()


答案 2

有一些工具可用于监视 VM 的内存使用情况。VM 可以使用 JMX 公开内存统计信息。您还可以打印 GC 统计信息,以查看内存在一段时间内的性能。

调用 System.gc() 可能会损害 GC 的性能,因为对象将过早地从新一代移动到旧代,并且弱引用将被过早清除。这可能会导致内存效率降低、GC 时间延长和缓存命中率降低(对于使用弱引用的缓存)。我同意你的顾问:System.gc()很糟糕。我甚至会使用命令行开关禁用它