在 Java 中是否收集了永久代空间垃圾?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3796427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Java is Permanent Generation space garbage collected?
提问by Ashish
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?
我已经读过永久代(或永久代)空间不是垃圾收集的。但是,在 CMS 收集中,我可以在我的 GC 日志中看到一些类正在卸载。那么是在完全收集还是 CMS 收集期间收集 perm gen 垃圾?
采纳答案by Sagar V
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 还包含类加载器,它们必须在使用结束时手动销毁,否则它们会保留在内存中并保持对堆上对象的引用。Sun/Oracle 博客站点上由 Jon Masamitsu 撰写的“Presenting the Permanent Generation”文章可能会对您有所帮助。
回答by Stephen C
In current generation JVMs, permgen is indeed collected like other parts of the heap. The visualgcpage 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 apparentlydid 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 incorrectlyattributed "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 allof 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 中时就会出现这种泄漏。发生泄漏是因为当某个已被替换的旧类的实例仍然可访问时。这导致对象的类可访问,这导致类加载器可访问,这导致所有旧类以及它们的代码对象、字符串文字以及它们的静态框架和静态都可访问。许多这些泄漏的对象都存在于永久空间中。
UPDATE
更新
As of Java 8, permgen no longer exists: PermGen elimination in JDK 8
从 Java 8 开始,永久代不再存在:JDK 8 中的永久代消除