❒ 方法区(Method Area)是各个线程共享的内存区域
✔ JDK7及其之前的方法区一般称为永久代,JDK8之后称为元空间
✔ 主要存储类class、接口interface、枚举enum、注解annotation以及运行时常量池等类型信息
✔ 虚拟机启动的时候创建,关闭虚拟机时释放
✔ 如果方法区域中的内存无法满足分配请求,则会抛出如java.lang.OutOfMemoryError: Metaspace(1.8) 或 java.lang.OutOfMemoryError: PermGen space(1.7)
❒ 可能导致方法区发生OOM异常
✔ 加载大量的第三方jar包
✔ Tomcat部署的工程过多(30~50个)
✔ 大量动态地生成反射类
✔ 关闭JVM就会释放这个区域的内存。
❒ 设置方法区内存的大小
✔ 方法区的大小不必是固定的,JVM可以根据应用的需要动态调整
(1) 通过 -XX:PermSize参数设置永久代初始分配空间。默认值是20.75MB
(2) 通过 -XX:MaxPermSize参数设置永久代最大可分配空间。32位机器默认是64MB,64位机器模式是82MB
(1) 元空间大小可以使用参数-XX:MetaspaceSize和-XX:MaxMetaspaceSize指定,替代JDK7中的永久代的初始值和最大值。
(2) 默认值依赖于具体的系统平台,取值范围是12 ~ 20MB。在Windows平台下,-XX:MetaspaceSize默认大约是20MB。
(3) 如果-XX:MaxMetaspaceSize的值是-1,表示没有空间限制。在默认情况下,虚拟机会耗尽所有的可用系统内存。
(4) 如果元空间发生溢出,虚拟机一样会抛出异常OutOfMemoryError:Metaspace。
❒ 什么是常量池
✔ 可以看作是一张表,虚拟机指令根据这张常量表找到要执行的类名、方法名、参数类型、字面量等信息
✔ javap -v xxx.class // 查看字节码结构(类的基本信息、常量池、方法定义)
❒ 运行时常量池
✔ 常量池是*class文件中的,当该类被加载,它的常量池信息就会放入运行时常量池,并把里面的符号地址变为真实地址