更新这个答案与Java 5-7相关,Java 8修复了这个问题:https://blogs.oracle.com/poonam/about-g1-garbage-collector,-permanent-generation-and-metaspace Kudos转到mt.uulu
对于 Java 5-7:
Oracle/Sun VM 对世界的标准看法是:类是永恒的。因此,一旦加载,即使没有人再关心,它们也会保留在内存中。这通常没有问题,因为您没有那么多纯粹的“设置”类(=用于设置一次,然后再也不会使用)。因此,即使他们占用1MB,谁在乎呢。
但最近,我们有像Groovy这样的语言,它们在运行时定义类。每次运行脚本时,都会创建一个(或多个)新类,并且它们会永远保留在PermGen中。如果您正在运行服务器,则意味着您有内存泄漏。
如果启用 GC,则 GC 也会扫描 PermGen,并删除不再使用的类。CMSClassUnloadingEnabled
[编辑]您还必须启用(感谢Sam Hasler)。看到这个答案:https://stackoverflow.com/a/3720052/2541UseConcMarkSweepGC
根据博客文章 Java JVM 的最完整的 -XX 选项列表,它确定是否在 CMS 垃圾回收器下启用了类卸载。缺省值为 。默认情况下,还有另一个调用的选项,它(可能)会影响其他垃圾回收器。false
ClassUnloading
true
这个想法是,如果GC检测到以前加载的类不再在JVM中的任何位置使用,它可以回收用于保存类字节码和/或本机代码的内存。
如果您当前正在使用 CMS 收集器,则设置 CMSClassUnloadingEnabled 可能有助于解决您的 permgen 问题。但是,您很可能没有使用CMS,或者您有一个真正的类装入器相关的内存泄漏。在后一种情况下,您的类永远不会在GC中显示为未使用...因此永远不会被卸载。
Aaron Digulla说“上课是永远的”。严格来说,这并不是真的,即使在纯粹的Java世界中也是如此。实际上,类的生存期与其类装入器相关联。因此,如果您可以安排类装入器被垃圾回收(这并不总是一件容易的事),那么它加载的类也将被垃圾回收。
实际上,这是在对 Web 应用进行热重新部署时发生的情况。(或者至少,如果你能避免导致permgen存储泄漏的问题,这就是应该发生的事情。
-
如何使用Java中的RESTful Web服务获取远程/客户端IP地址? 我已经在我的项目中编写了Rest Web服务。Web服务调用可能来自不同 machine.so 我需要通过REST Web服务找出IP地址。 从这个请求.getRemoteAddr()使用这个。 但是我不能使用getRemoteAddr()。因为我的请
-
从包含大量文件的zip文件中提取1文件的最快方法是什么? 我尝试了但它们也缺少一些东西。 LZMA SDK不提供一种如何使用的文档/教程,这非常令人沮丧。没有 javadoc。 虽然7z jbinding没有提供一种简单的方法来只提取1个文件,但是,它只提供了提取zip文件
-
输入/输出流在销毁时是否关闭? Java 中的 InputStreams 和 OutputStreams 是否在销毁时关闭()?我完全理解这可能是不好的形式(特别是在C和C++世界中),但我很好奇。 另外,假设我有以下代码: 无名的FileInputStream是否在p.load
-
Java 程序中的字符串大小是否有任何限制? 我有一个字符串定义为 字符串 xx 我可以分配的字符数是否有任何限制? 2) 我正在将用户输入分配给此字符串 xx。70%的人只说一个字。有时他们给出一个大句子,所以想知道可
-