面试必问,JVM内存模型扫盲( 三 )


5. 方法区方法区(Method Area)与堆一样 , 是所有线程共享的内存区域 , 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据 。
方法区只是 JVM 规范中定义的一个概念 , 针对 Hotspot 虚拟机 , JDK8 之前使用永久代(Permanent Generation , 简称 PermGen)实现 , JDK8 使用元空间(Metaspace)实现 。
JDK8 之前可以通过 -XX:PermSize 和 -XX:MaxPermSize 来设置永久代大小 , JDK8 之后 , 使用元空间替换了永久代 , 改为通过 -XX:MetaspaceSize 和 -XX:MaxMetaspaceSize 来设置元空间大小 。
运行时常量池运行时常量池(Runtime Constant Pool)是方法区中的一部分 , 用于存储编译期间生成的各种字面量和符号引用 。在Java程序运行时 , JVM将编译期生成的class文件中的常量池内容读取到运行时常量池中 。
运行时常量池存储了类和接口中的常量 , 包括字符串字面量、被声明为final的常量值等 。它还存储了类和接口中的符号引用 , 如类和接口、字段和方法的引用等 。
在JVM中 , 运行时常量池是线程安全的 。每个线程都有一个自己的线程栈 , 其中包含了局部变量表 , 而这些局部变量表中所引用的对象都位于堆中 。当一个线程需要引用运行时常量池中的常量时 , JVM会先将常量值从运行时常量池中复制到线程栈的局部变量表中 , 然后再进行引用 。
需要注意的是 , 在JDK8中 , 运行时常量池已经被移动到元空间(Metaspace)中 。元空间是在本地内存中分配的 , 与JVM的堆内存是分离的 , 因此不会受到Java堆大小的限制 。




推荐阅读