在Java中是永久生成的空间垃圾收集?

时间:2010-09-26 02:56:26

标签: java garbage-collection

我已经读过Perm gen(或Permanent Generation)空间不是垃圾收集的。但是,在CMS集合中,我可以在GC日志中看到一些类正在卸载。那么在完全收集或CMS收集期间收集的垃圾垃圾是什么?

2 个答案:

答案 0 :(得分:33)

PermGen像堆的其他部分一样被垃圾收集。

这里需要注意的是PermGen包含类和对象的元数据,即指向分配对象的堆的其余部分的指针。 PermGen还包含类加载器,它们必须在使用结束时手动销毁,否则它们将保留在内存中并且还保持对堆上对象的引用。 Jon Masamitsu在Sun / Oracle博客网站上发表的"Presenting the Permanent Generation"文章可能对您有帮助。

答案 1 :(得分:30)

在当前的JVM中,permgen确实像堆的其他部分一样被收集。 visualgc页面声明它与旧一代一起收集。

在较旧的JVM中,这显然并非总是如此。例如,在Java 5中,CMS收集器显然默认情况下不收集permGen:您可以使用-XX:+CMSPermGenSweepingEnabled启用它。我还记得听说过一些非常古老的JVM根本没有实现permgen集合,虽然我找不到可靠的源代码......呃......“factoid”。

另一点是,很多人错误地将“OutOfMemoryError:permgen”的例外归因于根本没有被收集的permgen。现实是不同的。这些OOME的最常见原因是当您将代码热加载到正在执行的JVM中时会出现一种潜在的存储泄漏。发生泄漏是因为当一个已被替换的旧类的实例仍然可以访问时。这会导致对象的类可以访问,这会导致类类加载器可以访问,从而导致可以访问旧类的所有,以及它们的代码对象,它们的字符串文字和它们的静态帧和静态。很多这些泄漏的物体都存在于permgen空间。


<强>更新

从Java 8开始,permgen不再存在:PermGen elimination in JDK 8

相关问题