方法区

定义


所有java 虚拟机线程共享的一块区域,存储了所有类相关信息,在虚拟机启动时被创建,JVM关闭就会释放方法区的空间。不同版本实现方式不同。例如永久代,元空间。

JDK1.6及之前:永久代。静态变量在永久代中

JDK1.7 :永久代。字符串常量池、静态变量移除,放入堆中。

JDK1.8及之后的实现方式:元空间。不在虚拟机设置的内存中,而是使用本地内存。类信息、字段、方法、常量保存在本地内存,但字符串常量池、静态变量仍在堆中。




方法区的内部结构


类的信息、属性、方法、异常表等。其中有他们的全类名,返回类型,权限修饰符等

从字节码文件看
从字节码文件看

被final修饰的属性在编译的时候就赋值了。

从字节码来看


方法区内存溢出


类加载的个数过多

1. 1.8以前会导致永久代内存溢出(使用MaxPermSize设置永久代大小)

2. 1.8以后会导致元空间内存溢出(使用系统内存,可以使用MaxMetaSpace设置元空间大小)


溢出场景

加载大量的第三方的jar包:Tomcat部署的工程过多(30-50个):大量动态的生成反射类

 实际场景中spring,mybatis:会产生大量的动态生成类


演示溢出



设置方法区内存大小


JDK 7 以前:

-XX:PermSize=100m

-XX:MaxPermSize=100m

JDK8及以后:

-XX:MetaspaceSize=100m

-XX:MaxMetaspaceSize=100m


如何解决OOM



方法区可以有垃圾回收也可以没有,方法区的垃圾收集主要回收两部分内容:常量池中废弃的常量和不再使用的类型。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容