一.运行时数据区域
线程私有的:程序计数器+虚拟机栈+本地方法栈
线程共享的:堆+方法区(运行时常量池)+直接内存(非运行时数据区的一部分)
*JDK1.8后将方法区废除,新增元空间。
1.1 程序计数器
记录指令的偏移地址,是唯一一个不会出现OutOfMemoryError的内存区域。
思考:为什么不会出现OutOfMemoryError?
OutOfMemoryError出现原因是由于运行时内存动态扩增导致内存不够用,而程序计数器是当执行到下一条指令的时候,改变的只是程序计数器中保存的地址,不需要申请新的内存来保存新的指令地址,因此,永远不会出现OutOfMemoryError
1.2 Java虚拟机栈
虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务
实际上,Java虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。
局部变量表主要存放了编译器可知的各种数据类型、对象引用。
1.3 本地方法栈
与虚拟机栈类似,只不过是为native方法服务
1.4 堆
垃圾收集管理(GC)的主要区域,主要存放对象实例,给对象和数组分配内存
1.5 方法区(目前由元空间取代)
存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
”永久代“用来实现方法区,使GC能像管理堆一样管理内存
*JDK1.8后被元空间取代,使用直接内存。
1.6 运行时常量池
用于存放编译期生成的各种字面量和符号引用,例如:String a="123"
JDK1.7后将运行时常量池从方法区中移了出来,在 堆(Heap)中指定一块区域存放运行时常量池。
1.7 直接内存
不属于JVM运行时数据区域,但也会发生OutOfMemoryError