PermGen空间是否减少了?

时间:2013-07-15 10:40:22

标签: java hibernate

我想知道JVM是否正常卸载类以减少PermGen空间。所以我的问题在这里:

  1. Java类是否默认从JVM中卸载?
  2. 关闭Jar类加载器是否从该jar中卸载所有已加载的类?
  3. 应该使用哪些命令/方法来卸载类?
  4. 仅供参考,我确实在网上尝试了一些解决方案,但没有人回答我的问题。 (例如:What does JVM flag CMSClassUnloadingEnabled actually do?

    PS:我指的是Java 6 + hibernate(类加载是由hibernate处理的)

4 个答案:

答案 0 :(得分:3)

摆脱加载类的唯一方法是允许JVM通过消除对此类加载器的所有引用来加载这些类的类加载器。当我们取消部署webapp时,这就是Web服务器中发生的情况。

答案 1 :(得分:3)

目前,默认情况下正在收集永久代。

  

永久世代由一个空间组成,但没有自己的收藏家。相反,这个空间是作为老一代的一部分收集的。

根据this visualgc页面。

在旧JVM中,您可以使用-XX:+CMSPermGenSweepingEnabled标志启用此功能。

当AFAIK类未从任何ClassLoader引用时,它们将被卸载。

java.lang.OutOfMemoryError: PermGen space错误是由类加载器中的内存泄漏引起的。取消部署/重新部署Web应用程序时的常见问题。

答案 2 :(得分:2)

假设你在谈论HotSpot,Oracle / Sun JVM。

  1. 如果没有引用它们。请注意,所有类都有对其类加载器的引用,反之亦然,并且所有对象都引用了它们的类。
  2. 也许。 “关闭”是什么意思?
  3. 使用选项-XX:+UseConcMarkSweepGC-XX:+CMSClassUnloadingEnabled启动JVM。这将允许卸载未使用的类,即使它们的类加载器仍然存在。
  4. 另见Unloading classes in java?

答案 3 :(得分:2)

Entity启动时,Hibernate会加载内存中的所有SessionFactory类。另一方面,只有在需要时,才会Hibernatelazy方式加载实体所有权。

GC需要内存时,JVM可以卸载类。 实体istances也是垃圾收集,但是,与任何其他对象一样,只有当没有更多的引用指向它们时。换句话说,如果Entity会话仍处于打开状态,则无法卸载Hibernate个问题。要卸载它们,您需要清除持久性上下文或关闭会话。