2013-03-20 49 views
0

我们有一个应用程序可以在垃圾收集之前生成数千个Java ClassLoaders和classes。我们确信没有类加载器泄漏,但是我们正在获得permgen错误(即使存在,这个问题也与任何潜在泄漏正交)。将Java ClassLoaders添加到堆而不是perm gen

有没有什么方法可以指定某些ClassLoaders及其加载的类放在堆中而不是放在perm gen中?

我们在Linux上使用Oracle JDK Java 6。


编辑:看起来像Java 8将不再有PermGen。它将被Metaspace取代。

http://java.dzone.com/articles/java-8-permgen-metaspace

回答

2

当然你要烫发根的错误 - 这就是类加载器把班。你会期待什么?

您可以将它们映射到字节缓冲区中,就像Java NIO一样,但它们不会堆积在堆上。

在采取非常措施之前,你应该尝试增加你的烫发代码。你需要多少烫发空间?使用Visual VM进行配置文件并查看。

+0

谢谢。 “当然,你会遇到烫发的错误 - 这就是班级装载员上课的地方,你期望什么?”我知道这一点,这就是我问这个问题的原因。如果这些对象可以放在常规内存中,那么我们不会得到permgen错误(我们可能会遇到堆错误,这可能有助于解决我们的问题)。我们目前使用了385M的PermGen,我不认为增加更多是个好主意。正如我所说的,可能会有泄漏,我们花了几天的时间使用Visual VM和YourKit来寻找它。事情可能会更容易追查,如果我们有堆错误,而不是permgen。 – 2013-03-20 22:57:31

+0

不是。内存是内存 - 分代传统是GC /内存模型设计的选择。为什么增加它不是一个好主意?如果你有堆错误,增加堆是否也是一个坏主意?这整个方法是错误的。 – duffymo 2013-03-21 00:05:44

1

有什么方法可以指定某些ClassLoaders及其加载的类放在堆中而不是放在perm gen中吗?

AFAIK,没有办法做到这一点。 AFAIK,permgen分配发生在JVM运行时深处,你无法得到它。 (我认为classloader本身并不存在于permgen中,我认为这只是JVM的内部数据结构,它们代表了类和它们的代码。)

如果你的应用程序真的需要这样工作,认为你别无选择,只能让permgen足够大。 (很明显,你应该检查,真正的问题不是PermGen的泄漏。)

然而,这让我感到你的应用程序的体系结构是相当奇怪的,如果它需要产生大量的类和类加载器。我希望看看它在做什么不能以另一种方式完成。

+0

是的,应用程序的架构很奇怪。我很乐意将结构调整为一种不同的方式,但这对于需要运行数百个创建,编译,运行和销毁Grails项目的测试的grails-ide来说很重要。 Grails使用Groovy,Groovy使用自定义类加载器来加载和编译脚本。感谢您的建议。我们会继续寻找。 – 2013-03-20 23:36:42

+0

听起来好像是时候转储Grails了。我不知道这是不好的。感谢您的高举。 – duffymo 2013-03-21 00:06:28

+0

该评论可能出错了。从用户的角度来看,Grails运行良好。当您运行grails命令并退出时,用于编译的自定义类加载器很有意义。我们现在遇到的问题是我们的IDE测试套件中存在permgen问题,因为我们需要在同一个进程中执行数百个命令。 – 2013-03-21 03:43:24