很多人认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾收集,而且在方法区进行垃圾收集的“性价比”一般比较低:在堆中,尤其是在新生代中,常规应用进行一次垃圾收集一般可以回收70%~95%的空间,而永久代的垃圾收集效率远低于此。

永久代的垃圾收集主要回收两部分内容:废弃常量和无用的类。回收废弃常量与回收Java堆中的对象非常类似。以常量池中字面量的回收为例,假如一个字符串“abc”已经进入了常量池中,但是当前系统没有任何一个String对象是叫做“abc”的,换句话说是没有任何String对象引用常量池中的“abc”常量,也没有其他地方引用了这个字面量,如果在这时候发生内存回收,而且必要的话,这个“abc”常量就会被系统“请”出常量池。常量池中的其他类(接口)、方法、字段的符号引用也与此类似。

判定一个常量是否是“废弃常量”比较简单,而要判定一个类是否是“无用的类”的条件则相对苛刻许多。类需要同时满足下面3个条件才能算是“无用的类”:

该类所有的实例都已经被回收,也就是Java堆中不存在该类的任何实例。

加载该类的ClassLoader已经被回收。

该类对应的java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

虚拟机可以对满足上述3个条件的无用类进行回收,这里说的仅仅是“可以”,而不是和对象一样,不使用了就必然会回收。是否对类进行回收,HotSpot虚拟机提供了-Xnoclassgc参数进行控制,还可以使用-verbose:class及-XX:+TraceClassLoading、 -XX:+TraceClassUnLoading查看类的加载和卸载信息。

在大量使用反射、动态代理、CGLib等bytecode框架的场景,以及动态生成JSP和OSGi这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出。

jvm回收方法区的更多相关文章

  1. JVM回收方法区内存

    很多人认为方法区(或者HotSpot虚拟机中的永久代)是没有垃圾收集的,Java虚拟机规范中确实说过可以不要求虚拟机在方法区实现垃圾收集,而且在方法区进行垃圾收集的“性价比”一般比较低:在堆中,尤其是 ...

  2. java虚拟机 jvm 方法区实战

    和java堆一样,方法区是一块所有线程共享的内存区域,用于保存系统的类信息,类的信息有哪些呢.字段.方法.常量池.方法区也有一块内存区域所以方法区的内存大小,决定了系统可以包含多少个类,如果系统类太多 ...

  3. JVM 方法区内存扩大 以及开启GC

    因为应用使用了OSGi框架,<深入理解JAVA虚拟机>中对使用OSGi时可能产生的方法区溢出有所描述 第一部分: 第二部分 可见,OSGi会动态生成大量Class,在OSGi中,即使是同一 ...

  4. jvm 方法区

    方法区在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内部 ...

  5. Jvm方法区以及static的内存分配图

    前面的几篇都没有太明确地指出 方法区 是什么?现在通过一些资料的收集和学习,下面做一些总结 什么是方法区: 方法区是系统分配的一个内存逻辑区域,是JVM在装载类文件时,用于存储类型信息的(类的描述信息 ...

  6. java虚拟机之回收方法区

    在java虚拟机中并没有规范规定需要对方法区即是新生代进行垃圾回收, 主要是这些区域的回收性价比极低, 一般在新生代中一般垃圾回收中可以达到70%到95%.   其中永久代中的垃圾回收主要回收的是两个 ...

  7. java虚拟机学习笔记(四)---回收方法区

    Java虚拟机规范中规定不要求虚拟机在方法区实现垃圾收集,而且在方法区实现垃圾收集性价比确实很低.在堆中,尤其是新生代,一次垃圾收集可以回收75%-95%的空间,而永久代的垃圾回收效率远低于此. 永久 ...

  8. Java回收方法区中回收的类

    回收的类必须满足下面三个条件才能算是“无用的类” 1.该类所有的实例都已经被回收,也就是说Java堆中不存在该类的任何实例: 2.加载该类的ClassLoader已经被回收: 3.该类对应的java. ...

  9. 垃圾收集GC

    一.引用计数法给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是不能再被使用的.引用计数法实现简单,判定效率也很高,但是它很 ...

随机推荐

  1. 轻量级IOC框架Guice

    java轻量级IOC框架Guice Guice是由Google大牛Bob lee开发的一款绝对轻量级的java IoC容器.其优势在于: 速度快,号称比spring快100倍. 无外部配置(如需要使用 ...

  2. 亮点面试题&amp;&amp;实现Singleton(辛格尔顿)模式-JAVA版本

    称号:设计一个类.我们只能产生这个类的一个实例.(来自<剑指Offer>) 解析:仅仅能生产一个实例的类是实现Singleton(单例)模式的类型.因为设计模式在面向对象程序设计中起着举足 ...

  3. Visual Studio 单元测试之四---Generic测试

    原文:Visual Studio 单元测试之四---Generic测试 这里的Generic我觉得理解为外部测试更合适.因为在这种测试模式下Visual Studio只是启动一个外部的程序,然后通过返 ...

  4. C# 我的注册表操作类

    using System; using System.Collections.Generic; using System.Text; using Microsoft.Win32; using Syst ...

  5. UC编程:输入输出重定向(系统调用)

    在Unix下,系统重定向是使用dup和dup2函数完成的 在学习使用这两个函数之前,必须要搞懂一个概念就是文件描述符 摘自:<文件描述符和文件指针的区别> 文件描述符就是open文件时产生 ...

  6. Spring MVC 的 研发之路

    翻译器:intellij idea 一个.创建spring mvcproject   一个. 二. 三. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcX ...

  7. return 使用和闭包

    1.return 使用 案例一: var a=1; for(var b=0; b<10; b++){ return b; }; sonsole.log(b)//返回为空 个人认为此处左右与为全局 ...

  8. Reactive Extensions

    Rx提供了一种新的组织和协调异步事件的方式,极大的简化了代码的编写.Rx最显著的特性是使用可观察集合(Observable Collection)来达到集成异步(composing asynchron ...

  9. 2014.3.4-C语言学习小结

    位操作: 知识点: 1.位运算符 2.位移运算符 1.将指定位设置为12.将指定位设置为03.获取指定位的内容 ==========================复习二进制 1.二进制转换 10-- ...

  10. .net实现依赖注入

    .net实现依赖注入 1. 问题的提出 开发中,尤其是大型项目的开发中,为了降低模块间.类间的耦合关系,比较提倡基于接口开发,但在实现中也必须面临最终是“谁”提供实体类的问题.Martin Fowle ...