一、概述二、方法区内部结构
1、类型信息2、域(成员变量/属性)和方法信息3、类加载器信息5、javap -v 字节码文件名.class 三、方法区的垃圾回收
1、废弃常量2、不使用的类型
一、概述对于方法区,我们根据官方文档,可以明确的一点是:
“方法区逻辑上属于堆空间,但是方法区可以不像堆空间一样,进行GC和压缩”所以我们常常将方法区和堆分离开来讨论。但我们又会在方法区中进行一些垃圾的回收(它不像堆中那么简单和彻底),Java虚拟机规范中对这一块设计规范较为宽松,我们暂且这么认为。
方法区存储被jvm加载的类型信息、常量、静态变量等数据
1、类型信息 2、域(成员变量/属性)和方法信息域(File)信息:
方法信息:
方法区中会存储类的加载器,java程序经过静态编译后编程字节码文件(.class)字节码文件会随着某个类加载器加载到JVM的方法区中,一个类只有唯一的一个类加载器。
当对方法区回收时,可对没用的类加载器进行回收。
5、javap -v 字节码文件名.class在idea中的local中输入:javap -v 字节码文件名.class
可以对字节码文件进行解析,可以查看类、域、方法、常量池信息等。
ps:在输入命令前要使用cd命令进入到文件目录
也可以在idea中安装jclasslib Bytecode viewer插件进行可视化。
概述中我们讲了方法区可以不实现垃圾回收,其实方法区有一些垃圾回收:
常量池中废弃的常量不再使用的类型
说白了,垃圾回收也就是回收类信息和常量池信息!
1、废弃常量
对于废弃常量的回收很简单,只要不使用了(没用任何地方引用),就会被回收。
常量池中主要存放两大类常量——字面量和符号引用:
字面量:
文本字符串final声明的常量
符号引用:
类和接口的全限定名字段的名称和描述符方法的名称和描述符 2、不使用的类型
对于类信息的回收不再那么简单,条件十分苛刻,需要同时满足以下三个条件:
但是我们在大量使用反射、动态代理、CGLib等字节码框架这种频繁自定义类加载的场景中,需要对类信息进行回收,防止对方法区内存造成压力。
参考资料:
尚硅谷宋红康JVM全套讲解.



