方法区(Method Area)非堆
方法区是各线程共享的内存区域,它用于存储已被JVM加载的类信息、常量、静态变量、运行时常量池等数据
Java堆(Java Heap)
Java堆是各线程共享的内存区域,在JVM启动时创建,这块区域是JVM中最大的, 用于存储应用的对象和数组,也是GC主要的回收区,一个 JVM 实例只存在一个堆内存,堆内存的大小是可以调节的。类加载器读取了类文件后,需要把类、方法、常变量放到堆内存中,以方便执行器执行,堆内存分为三部分:新生代、老年代、永久代。
说明:
- Jdk1.6及之前:常量池分配在永久代 。
- Jdk1.7:有,但已经逐步“去永久代” 。
- Jdk1.8及之后:无永久代,改用元空间代替(java.lang.OutOfMemoryError: PermGen space,这种错误将不会出现在JDK1.8中)。
- DK 1.8 的时候,方法区被彻底移除了(JDK1.7就已经开始了),取而代之是元空间,元空间使用的是直接内存
- JDK1.7及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池
本地方法栈(native method stack)
这部分主要与虚拟机用到的 Native 方法相关,一般情况下, Java 应用程序员并不需要关心这部分的内容。
虚拟机栈(vm stack)
每个线程有一个私有的栈,随着线程的创建而创建。存放了局部变量表(基本数据类型和对象引用)、操作数栈、方法出口等信息
程序计数器(Program Counter Register)
JVM支持多个线程同时运行,每个线程都有自己的程序计数器。倘若当前执行的是 JVM 的方法,则该寄存器中保存当前执行指令的地址;倘若执行的是native 方法,则PC寄存器中为空
运行时常量池
运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用