【问题标题】:Java memory usage stays well within max heap size, but my system memory is slowly being eatenJava 内存使用率保持在最大堆大小内,但我的系统内存正在慢慢被吃掉
【发布时间】:2011-11-30 20:53:24
【问题描述】:

我对 Java 编程比较陌生,所以请耐心等待我试图了解这里发生了什么。

我开发的应用程序使用的最大堆大小为 256MB。随着 GC 的完成,我从来没有遇到过任何问题。加载大图像时会建立使用的堆,并在卸载时很好地释放。我还没有看到内存不足错误。

但是...运行应用程序大约一个小时。我注意到该进程使用了​​越来越多的系统内存,而这些内存永远不会被释放。所以应用程序开始时使用了大约 160MB,随着堆大小的增加而增加,但是当堆大小缩小时,使用的系统内存只会越来越多。直到进程使用 2.5GB 并且我的系统开始变慢。

现在我正试图了解幸存的世代。似乎堆大小和幸存的世代并没有真正相互联系?我的应用程序建立了很多幸存的世代,但我从来没有根据应用程序本身使用的内存耗尽内存。但是 JVM 一直在吃内存,从不把它还给系统。

我在网上搜索,有时会找到一些有用的信息。但我没有得到的是应用程序很好地保持在堆大小边界内,并且我的系统内存仍然被吃掉了。

这是怎么回事?

我在 OSX Lion 上使用 NetBeans IDE,并提供最新的 1.6 JDK。

【问题讨论】:

  • 您是否尝试过使用 VisualVM 戳您的应用程序?它应该有一个查看堆转储的工具,也许知道哪些对象正在占用旧代会有所帮助。
  • 您确定您正确处置所有资源吗?某些类(例如 ImageReader)可以保留一些本机资源,当对象本身在 JVM 中收集时,这些资源不会自动释放。通常你需要使用 finally-blocks 来确保这些资源被释放。
  • 所以你有一个 256m 的 -Xmx 但进程大小增长到 2.5gb?哇。我从来没有见过这样的行为。你用了多少线程?

标签: java macos memory memory-leaks


【解决方案1】:

最好的开始方法是在同一台机器上的 JDK 中使用jvisualvm。附加到您正在运行的程序并启用分析。

另一种选择是尝试在调试模式下运行应用程序并不时停止它以检查您的数据结构。这听起来像是一种破碎/奇怪的做法,但通常如果你有内存泄漏,它在哪里就会变得非常明显。

祝你好运!

【讨论】:

  • 我一直在使用 NetBeans 分析器进行分析,它实际上与 jvisualvm 有点相同。 Windows PC 上的堆大小远低于 64MB,而堆大小不受限制。在 OSX 上,堆大小现在增加到最大 128MB。但是……系统使用的内存还在不断增长。根据分析器,有几个幸存的世代,图中幸存的世代仍然保持增长。这是一个动态的应用程序。对象不断被创建和丢弃。
猜你喜欢
  • 2013-05-24
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-05-13
相关资源
最近更新 更多