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

时间:2022-10-29 23:55:23

I have read that Perm gen (or Permanent Generation) space is not garbage collected. However, in CMS collection I can see some classes unloading in my GC log. So is perm gen garbage collected during full collection or CMS collection?

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

2 个解决方案

#1


32  

The PermGen is garbage collected like the other parts of the heap.

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

The thing to note here is that the PermGen contains meta-data of the classes and the objects i.e. pointers into the rest of the heap where the objects are allocated. The PermGen also contains Class-loaders which have to be manually destroyed at the end of their use else they stay in memory and also keep holding references to their objects on the heap. The "Presenting the Permanent Generation" article by Jon Masamitsu on the Sun / Oracle blog site might help you.

这里需要注意的是PermGen包含类和对象的元数据,即指向分配对象的堆的其余部分的指针。 PermGen还包含类加载器,它们必须在使用结束时手动销毁,否则它们将保留在内存中并且还保持对堆上对象的引用。由Jon Masamitsu撰写的关于Sun / Oracle博客网站的“呈现永久一代”文章可能会对您有所帮助。

#2


28  

In current generation JVMs, permgen is indeed collected like other parts of the heap. The visualgc page states that it is collected together with the old generation.

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

In older JVMs this was apparently not always so. For instance, in Java 5 the CMS collector apparently did not collect permGen by default: you could enable it with -XX:+CMSPermGenSweepingEnabled. I also recall hearing that some really old JVMs did not implement permgen collection at all, though I cannot find a reliable source for this ... ermm ... "factoid".

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

The other point, is that a lot of people have incorrectly attributed "OutOfMemoryError : permgen" exceptions to permgen not being collected at all. The reality is different. The most common cause of these OOME's is an insidious kind of storage leak that manifests when you hot-load code into an executing JVM. The leak occurs because when an instance of some old class that has been replaced remains reachable. This causes the object's class to be reachable, which causes the classes classloader to be reachable, which causes all of the old classes to be reachable, together with their code objects, their string literals, and their static frames and static. A lot of these leaked objects live in permgen space.

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


UPDATE

As of Java 8, permgen no longer exists: PermGen elimination in JDK 8

从Java 8开始,permgen不再存在:JDK 8中的PermGen消除

#1


32  

The PermGen is garbage collected like the other parts of the heap.

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

The thing to note here is that the PermGen contains meta-data of the classes and the objects i.e. pointers into the rest of the heap where the objects are allocated. The PermGen also contains Class-loaders which have to be manually destroyed at the end of their use else they stay in memory and also keep holding references to their objects on the heap. The "Presenting the Permanent Generation" article by Jon Masamitsu on the Sun / Oracle blog site might help you.

这里需要注意的是PermGen包含类和对象的元数据,即指向分配对象的堆的其余部分的指针。 PermGen还包含类加载器,它们必须在使用结束时手动销毁,否则它们将保留在内存中并且还保持对堆上对象的引用。由Jon Masamitsu撰写的关于Sun / Oracle博客网站的“呈现永久一代”文章可能会对您有所帮助。

#2


28  

In current generation JVMs, permgen is indeed collected like other parts of the heap. The visualgc page states that it is collected together with the old generation.

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

In older JVMs this was apparently not always so. For instance, in Java 5 the CMS collector apparently did not collect permGen by default: you could enable it with -XX:+CMSPermGenSweepingEnabled. I also recall hearing that some really old JVMs did not implement permgen collection at all, though I cannot find a reliable source for this ... ermm ... "factoid".

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

The other point, is that a lot of people have incorrectly attributed "OutOfMemoryError : permgen" exceptions to permgen not being collected at all. The reality is different. The most common cause of these OOME's is an insidious kind of storage leak that manifests when you hot-load code into an executing JVM. The leak occurs because when an instance of some old class that has been replaced remains reachable. This causes the object's class to be reachable, which causes the classes classloader to be reachable, which causes all of the old classes to be reachable, together with their code objects, their string literals, and their static frames and static. A lot of these leaked objects live in permgen space.

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


UPDATE

As of Java 8, permgen no longer exists: PermGen elimination in JDK 8

从Java 8开始,permgen不再存在:JDK 8中的PermGen消除