深入理解Java虚拟机之回收方法区

来源:互联网 发布:教育网络策划方案 编辑:程序博客网 时间:2024/06/04 19:28

深入理解Java虚拟机之回收方法区

      很多人认为在Java虚拟机中,方法区是不存在垃圾回收的,因此方法区也成为永久代,在Java虚拟机规范中的确没有要求方法区进行垃圾回收,这是因为方法区的垃圾回收“性价比”比较低,在堆中进行一次GC,往往可以回收75%到95%的空间,而在方法区中的回收效率远远低于此值。
      所以,方法区并不是没有垃圾回收,在方法区的垃圾回收主要分为两个部分:对废弃常量的回收和对不使用的类进行回收。

  • 对废弃常量的回收比较简单,基本上和堆里面的对象实例回收很相似,当一个常量没有任何地方引用的时候,就可以把这个常量进行回收掉了。例如在字符串常量池中有一个“abc”的字符串,如果没有任何一个String对象引用常量池中的“abc”字符串,那么当方法区发生内存回收而且必要的话,就会把“abc”字符串回收掉。常量池中其他的类、接口、方法、字段的符号引用也是这样。
  • 相对于对常量的判断,对一个类判断是否有用则要复杂许多,一个类要同时满足三个条件,才能被回收掉:
          1、这个类的所有实例都已经被回收掉了,在Java堆中不存在任何该类的实例。
          2、加载该类的ClassLoader已经被回收了。
          3、这个类对应的Class对象没有在任何地方被引用,无法通过反射的方法创建类对象或调用类的方法。
    满足这三个条件的类是可以被回收的。当然仅仅是可以,并不是必然要被回收。是否对类进行回收可以通过配置参数来配置,通过-Xnoclassgc进行控制,以及使用-verbose:classyiji -XX:+TraceClassLoading、-XX:+TraceClassUnLoading查看类加载和类卸载的信息。在大量使用反射、动态代理、动态生成JSP等频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以此来保证方法区不会溢出。
阅读全文
0 0
原创粉丝点击