在 IBM iSeries 系统上,我有一个 Java 程序正在运行 - 一个带有 Web 服务器组件的应用程序服务器,所有这些都是内部开发的。在 32 位或 64 位 J9 JVM(IBM Technology for Java)上运行时,我有内存泄漏的症状。
请注意,在 iSeries 经典 JVM、多个 Sun/Oracle JVM 和 Linux JVM 上运行该软件不会出现任何问题。哎呀,当我在我的网站上工作时,我经常让相同的软件在我妻子的入门级笔记本电脑上运行数周——我可以向你保证,如果它泄漏了内存,它会在那个东西上被注意到。
如果我只是让一个普通的系统闲置,没有配置应用程序(基本上只有消息传递系统和 Web 服务器),堆只会继续缓慢增长,导致随着时间的推移分配更多内存,每个 GC 周期不会相当收集到以前的水平。对于没有问题的 JVM,该模式完全相同,除了那些 GC 扫描总是将堆减少到其先前的 GC 级别。
但是,如果我在稳定之后在启动时提取 JVM 系统转储,并且在分配的堆显着增长后进行后续转储,则差异比较表明运行一周后的可访问对象比启动时更多。最近的一个,在一周后显示加载了 6 个附加类和一些与之明显相关的对象。对所有活体的彻底审查没有显示出任何出乎我意料的事情。
我已经尝试过优化吞吐量和分代并发垃圾收集器。
所以根据作业的堆大小,我们似乎在泄漏,根据堆转储,没有任何泄漏。
没有调用任何 JNI 方法(除了作为核心 JVM 的一部分运行的本机代码),而且肯定是堆在增长 - 我可以在 IBM WRKJVMJOB 信息中清楚地看到这一点,并在我的控制台中使用 JMX bean 进行报告日志文件。
到目前为止,我无法使用 JVisualVM 等 JMX 工具连接到活动 JVM,因为尽管在正确配置时会创建侦听套接字,但连接被拒绝,显然是在协议级别(TCP/IP 堆栈显示已接受的连接,但JVM 反弹它)。
我很困惑,不知道下一步该去哪里。
编辑:只是为了澄清;这些结果都是使用未检测的 JVM,因为我无法通过 JMX 访问该 JVM(我们正在与 IBM 合作)。
编辑 2011-11-16 19:27:我能够提取超过 1823 个 GC 周期的 GC 活动报告,其中包括 Soft/Weak/PhantomReference 计数的特定计数;这些数字没有出现失控增长的迹象。然而,小对象永久空间有显着增长(大对象永久空间是空的)。它从 9M 增长到 36M。