我继承了一个Java小程序(实际的),该小程序在运行大约4天后抛出OutOfMemory异常。小程序的性质使得人们确实会长时间打开它。
运行近两天后,jmap -histo将最大的堆使用者显示为:
num #instances #bytes类名称
------------ ------ ----------
1:14277 7321880
2:59626 5699968
3:14047 5479424
4:14277 5229744
5:59626 4778944
6:71026 3147624
麻烦是,我不明白这些东西是什么。至少发生了两件事:constantPoolKlass + constantPoolCacheKlass + instanceKlassKlass看起来是相关的,就像constMethodKlass + methodKlass一样。从名称中,它们看起来与类加载器有关。
如果我不得不猜测,小程序将创建约14,277个对象,其中每个对象约有4个方法,总共约59626个方法。但是,jmap输出不会显示具有如此大量实例的任何类,也不会看起来像其他类对象的总数之和达到14277。所以也许我对这些对象的作用不正确。有人可以解释吗?
最佳答案
是的,看起来您在泄漏类加载器。如果您实际上不是在自己的代码中创建类加载器(通常是通过URLClassLoader.newInstance或XSLT创建),则它可能与重新加载小程序有关(尽管您通常会返回相同的类加载器)。泄漏的可能原因是ThreadLocal,JDBC驱动程序和java.beans。