内存泄漏,没有对象数量或大小增加 [英] Memory leaking without objects growing in number or size

查看:150
本文介绍了内存泄漏,没有对象数量或大小增加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在IBM iSeries系统上,我运行了一个Java程序 - 一个带有Web服务器组件的应用程序服务器,所有这些都是内部开发的。在32位或64位J9 JVM(IBM Technology for Java)上运行时,我有内存泄漏的症状。

On an IBM iSeries system, I have a Java program running - an application server with a web server component, all in-house developed. When running on the 32 bit or 64 bit J9 JVM (IBM Technology for Java) I have symptoms of a memory leak.

请注意,在iSeries经典JVM,多个Sun / Oracle JVM和Linux JVM上运行此软件时没有出现任何问题。哎呀,我经常在我妻子的入门级笔记本电脑上运行相同的软件几周,而我正在我的网站上工作 - 我可以向你保证,如果它泄漏了内存,就会注意到那件事。

Note that no problems are seen running this software on the iSeries classic JVM, on multiple Sun/Oracle JVMs and on Linux JVMs. Heck, I routinely leave the identical software running for weeks at a time on my wife's entry-level laptop while I am working on my website - I can assure you if it was leaking memory it would be noticed on that thing.

如果我只是让一个普通的系统运行空闲,没有配置应用程序(基本上只是消息系统和Web服务器),堆只会继续缓慢增长,从而导致更多的内存随着时间的推移分配,每个GC周期都没有完全收集到以前的水平。对于没有问题的JVM,模式完全相同,除了那些GC扫描总是将堆减少到之前的GC级别。

If I just leave a plain-vanilla system running idle, with no applications configured (basically just the messaging system and a web server), the heap just continues to slowly grow, causing more memory to be allocated over time, with each GC cycle not quite collecting down to the previous level. The pattern is exactly the same for JVMs where there is no problem, except that on those the GC sweep always reduces the heap to its previous GC level.

但是,如果我拉一个JVM系统转储在分配堆显着增长后稳定和后续转储之后的启动时,差异比较表明运行一周后不再有可达的对象比启动时更多。最近的一个,一周后显示6个额外的类加载和一些明确相关的对象。对所有活动对象的彻底评论都没有显示出任何让我意想不到的消息。

But, if I pull a JVM system dump at startup after stabilizing and subsequent dumps after the allocated heap has grown significantly, differential comparison indicates that the are no more reachable objects after running for a week than there were at startup. The most recent one, after a week show 6 additional classes loaded and a few objects clearly related to that. Thorough reviews of all the live objects have shown nothing which leaps out at me as unexpected.

我尝试过优化吞吐量和代际并发垃圾收集器。

I have tried the optimized-for-throughput and the generational-concurrent garbage collectors.

因此,根据作业的堆大小,我们似乎正在泄漏,并且根据堆转储,没有任何泄漏。

So according to the job's heap size, we appear to be leaking, and according to heap dumps, nothing is leaking.

没有调用JNI方法(除了作为核心JVM的一部分运行的本机代码),它肯定是正在增长的堆 - 我可以清楚地看到IBM WRKJVMJOB信息以及使用JMX报告我的控制台日志文件中的bean。

There are no JNI methods being invoked (other than native code running as part of the core JVM), and it's definitely the heap which is growing - I can see that clearly in the IBM WRKJVMJOB information as well as reported using JMX beans in my console log file.

到目前为止,我不能使用JVisualVM之类的JMX工具连接到活动JVM,因为尽管在正确配置时创建了listen套接字,连接被拒绝,显然是在协议级别(TCP / IP堆栈显示已接受的连接,但JVM将其反弹)。

I cannot, so far, connect to the active JVM using JMX tools like JVisualVM because, although the listen socket is created when properly configured, the connection is rejected, apparently at a protocol level (the TCP/IP stack shows an accepted connection, but the JVM bounces it).

我很困惑,并且在关于下一步该去哪里的损失。

I am confounded, and at a loss as to where to go next.

编辑:只是为了澄清;这些结果都是使用未经检测的JVM,因为我无法获得对此JVM的JMX访问权限(我们正在与IBM合作)。

Just to clarify; these results are all with an uninstrumented JVM because I cannot get JMX access to this JVM (we are working on that with IBM).

编辑2011-11-16 19: 27:我能够在1823个GC循环中提取GC活动报告,其中包括Soft / Weak / PhantomReference计数的具体计数;这些数字并没有出现失控增长的迹象。然而,小物体的终身空间显着增长(大物体的终身空间是空的)。它从9M增长到36M。

EDIT 2011-11-16 19:27: I was able to pull a GC activity report over 1823 GC cycles which includes specific counts for Soft/Weak/PhantomReference counts; there is no sign of runaway growth in those numbers. There is, however significant growth in the small object tenured space (the large object tenured space is empty). It's grown from 9M to 36M.

推荐答案

在我的程序中消除了一些粗心的内存浪费(尽管没有任何泄漏),并且为了我们的工作量而更好地调整了GC,我已经将失控的内存使用降低到可容忍的水平。

Having eliminated some careless memory waste of memory (though not any leaks) in my program, and tuned the GC better for our workload, I have brought down the runaway memory use to a tolerable level.

但是,在此过程中我已经演示了IBM J9 JVM在AS / 400(也称为iSeries,Systemi,i5等)上使用的1336字节/分钟泄漏总计2 MB /天。我可以通过各种程序从一线测试程序一直到我们的应用程序服务器来观察这种泄漏。

However, in the process I have demonstrated that the IBM J9 JVM used on the AS/400 (aka iSeries, Systemi, i5, et al) has an 1336 byte/minute leak totaling 2 MB/day. I can observe this leak with a variety of programs from a "one-line" test program all the way up to our application server.

单行测试程序是这个:

public class ZMemoryLeak2
extends Object
{

static public synchronized void main(String... args) {
    try { ZMemoryLeak2.class.wait(0); } catch(InterruptedException thr) { System.exit(0); }
    }

}

还有一个单独的测试程序,除了通过JMX API监视内存使用情况之外什么都没做,最终显示1336 B以1分钟的间隔泄漏,永远不会被回收(好吧,在运行2周后没有回收)。 OP注意:JVM的每个变体的数量实际上略有不同。

And a separate test program that did nothing except monitor memory use via the JMX API showed conclusively that 1336 B is leaked at exactly 1 minute intervals, never to be reclaimed (well, not reclaimed after 2 weeks of running). OP Note: It was actually slightly different amounts on each variation of the JVM.

更新2012-04-02 :这被接受为IBM几周前的bug;它实际上是在去年年中的Java 5中找到并修补的,Java 6的补丁预计将在下一周或两周内发布。

Update 2012-04-02: This was accepted as a bug by IBM a few weeks ago; it was actually found and patched in Java 5 about the middle of last year, and the patch for Java 6 is expected to be available in the next week or two.

这篇关于内存泄漏,没有对象数量或大小增加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆