JVM中方法区概述

137 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

JVM中方法区概述

一、概述

对于方法区,我们根据官方文档,可以明确的一点是: ==“方法区逻辑上属于堆空间,但是方法区可以不像堆空间一样,进行GC和压缩”所以我们常常将方法区和堆分离开来讨论==。但我们又会在方法区中进行一些垃圾的回收(它不像堆中那么简单和彻底),Java虚拟机规范中对这一块设计规范较为宽松,我们暂且这么认为。 在这里插入图片描述

二、方法区内部结构

方法区存储被jvm加载的类型信息、常量、静态变量等数据

1、类型信息

在这里插入图片描述

2、域(成员变量/属性)和方法信息

域(File)信息: 在这里插入图片描述 方法信息: 在这里插入图片描述

3、类加载器信息

方法区中会存储类的加载器,java程序经过静态编译后编程字节码文件(.class)字节码文件会随着某个类加载器加载到JVM的方法区中,一个类只有唯一的一个类加载器。 在这里插入图片描述

当对方法区回收时,可对没用的类加载器进行回收。

5、javap -v 字节码文件名.class

在idea中的local中输入:javap -v 字节码文件名.class 可以对字节码文件进行解析,可以查看类、域、方法、常量池信息等。 ps:在输入命令前要使用cd命令进入到文件目录 在这里插入图片描述 也可以在idea中安装jclasslib Bytecode viewer插件进行可视化。 在这里插入图片描述

三、方法区的垃圾回收

概述中我们讲了方法区可以不实现垃圾回收,其实方法区有一些垃圾回收:

  • 常量池中废弃的常量
  • 不再使用的类型 在这里插入图片描述 在这里插入图片描述 说白了,垃圾回收也就是回收类信息和常量池信息!

1、废弃常量

对于废弃常量的回收很简单,只要不使用了(没用任何地方引用),就会被回收

常量池中主要存放两大类常量——字面量和符号引用:

字面量:

  • 文本字符串
  • final声明的常量

符号引用:

  • 类和接口的全限定名
  • 字段的名称和描述符
  • 方法的名称和描述符

2、不使用的类型

对于类信息的回收不再那么简单,条件十分苛刻,需要同时满足以下三个条件: 在这里插入图片描述 但是我们在大量使用反射、动态代理、CGLib等字节码框架这种频繁自定义类加载的场景中,需要对类信息进行回收,防止对方法区内存造成压力。

参考资料: 尚硅谷宋红康JVM全套讲解.