很多人认为方法区(或者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. leetcode 34 Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  2. 记第五届山东省ACM程序设计比赛——遗憾并非遗憾

    记第五届山东省ACM程序设计比赛 5月10日上午9点半左右,我们的队伍从学校出发,一个多小时后到达本次比赛的地点-哈尔滨工业大学. 报道,领材料,吃午饭,在哈工大的校园里逛了逛,去主楼的自习室歇息了一 ...

  3. js实现在新标签页打开页面

    这种方法打开新标签页要在IE9+以上浏览器才可以! <html> <head> <meta http-equiv="Content-type" con ...

  4. robin 今日南

    我很高兴,在学校体育馆看到李彦宏博士. 这是第一个真正的一次在媒体上看到,只能看到人才足够多的人,现实,我觉得非常好. 我不是一个真正罗宾的粉丝.百度是不是很热衷于这家公司.,但现在我仍然兴奋,我会被 ...

  5. mvc+EF比较好的框架

    个人看了传智播客的一位讲师搭建的框架感觉很好,就自己通过模仿划了一下很不讲究的类图来学习之间的关系(有些地方可能有自己理解不对的地方).很感激那位讲师,我会把这个框架用在我自己的项目中.

  6. 【Oracle】-【插入读取顺序】-插入读取之间的顺序关系

    Oracle插入记录的顺序是否是读取的顺序? 通过一个简单的实验验证: SQL> create table t ( x int, a char(2000) default 'x', b char ...

  7. Step one : 熟悉HTML

    //H1 1 <html> <head> <title>BeiJing</title> </head> <body> <h ...

  8. Step one : 熟悉Unix/Linux Shell 常见命令行 (二)

    2.学会使用一些文本操作命令 sed -- stream editor 1. Sed简介sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pat ...

  9. 大数据工具篇之Hive与HBase整合完整教程

    大数据工具篇之Hive与HBase整合完整教程 一.引言 最近的一次培训,用户特意提到Hadoop环境下HDFS中存储的文件如何才能导入到HBase,关于这部分基于HBase Java API的写入方 ...

  10. linux下开机启动脚本的方法

    1.准备好要随机启动的程序,例如 /root/test.sh .确保其可执行. 2.在目录 /etc/init.d/ 下编写控制脚本 test . #!/bin/sh ### BEGIN INIT I ...