我想知道 JVM 是否通常会卸载类以减少 PermGen 空间。所以这里是我的问题:
- 默认情况下,Java 类是否会从 JVM 中卸载?
- 关闭 Jar 类加载器是否会从该 jar 中卸载所有加载的类?
- 应该使用哪些命令/方式来允许卸载类?
仅供参考,我确实尝试了网络上的一些解决方案,但没有一个回答我的问题。(例如:JVM flag CMSClassUnloadingEnabled 实际上是做什么的?)
PS:我指的是Java 6 + hibernate(类加载由hibernate处理)
我想知道 JVM 是否通常会卸载类以减少 PermGen 空间。所以这里是我的问题:
仅供参考,我确实尝试了网络上的一些解决方案,但没有一个回答我的问题。(例如:JVM flag CMSClassUnloadingEnabled 实际上是做什么的?)
PS:我指的是Java 6 + hibernate(类加载由hibernate处理)
摆脱已加载类的唯一方法是允许 JVM 通过消除对该类加载器的所有引用来 GC 加载这些类的类加载器。当我们取消部署 web 应用程序时,这就是 web 服务器中发生的情况。
目前默认收集永久代。
永久代由单个空间组成,但没有自己的收集器。相反,这个空间是作为老一代的一部分收集的。
根据这个visualgc页面。
在旧的 JVM 中,您可以使用该-XX:+CMSPermGenSweepingEnabled
标志启用它。
当没有从任何 ClassLoader 引用 AFAIK 类时,它们会被卸载。
java.lang.OutOfMemoryError: PermGen space
错误是由类加载器中的内存泄漏引起的。取消部署/重新部署 Web 应用程序时的常见问题。
假设您在谈论 HotSpot,即 Oracle/Sun JVM。
-XX:+UseConcMarkSweepGC
使用选项和启动 JVM -XX:+CMSClassUnloadingEnabled
。这将允许卸载未使用的类,即使它们的类加载器仍然存在。另请参阅在 java 中卸载类?
Hibernate在启动Entity
时加载内存中的所有类。SessionFactory
另一方面,实体实例仅在需要时Hibernate
以某种方式加载。lazy
GC
当JVM
需要内存时,可以卸载类。实体 istances 也被垃圾收集,但与任何其他对象一样,只有当没有更多引用指向它们时。换句话说,如果会话仍然打开Entity
,则无法卸载 istances 。Hibernate
要卸载它们,您需要清除持久性上下文或关闭会话。