JVM——运行时数据区域

时间:2022-01-01 09:56:52

java虚拟机在执行java程序的时候将把它管理的内存划分为多个不同的数据区域,这些区域各有用途。


程序计数器(PCR):是一块较小的内存空间,可以看成是当前线程所执行的字节码的行号指示器,指向当前执行的指令。由于java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式实现的,任意时刻一个处理器只能有一个线程在运行,线程切换后需要回到它的正确执行位置,所以每个线程都有自己的程序计数器,每条线程之间的计数器互不影响,独立存储。我们这类内存区域为“线程私有”内存。


java虚拟机栈:与程序计数器一样也是线程私有内存。每个方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用到结束对应着一个栈帧的进栈和出栈。

局部变量表存放编译期可知的各种基本数据类型(short  byte  char  int float  long  double)、对象引用(不是对象本身,可能是一个指向对象的指针) 和 returnAddress 类型。


本地方法栈:与虚拟机栈发挥的作用非常相似,区别是java虚拟机栈执行的是java方法(也就是字节码)服务,而本地栈则为虚拟机使用到的Native方法服务。


java堆(java Head):对于大多数应用来说java 堆是java虚拟机所管理的内存中最大的一块。java堆是线程共享的一块内存区域,在虚拟机启动时创建。用来存放对象实例,几乎所有的对象实例和数组都在这里分配内存。

java 堆 是垃圾回收器管理的主要区域。java虚拟机规范规定:java堆可以处于物理上不连续的内存空间,只要逻辑上可连续的就行。


方法区:与堆一样是各个线程共享的区域,用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。


运行时常量池:是方法区的一部分。Class文件除了有类的版本、字段、方法、接口等描述信息外还有一项就是运行时常量池,用于存放编译期生成的各种字面量和符号引用。相对于Class文件池,运行时常量池具备动态性。受方法区内存的限制。


直接内存:直接内存不是java虚拟机运行时数据区的一部分,但是这部分内存被频繁用到。它不受java堆的限制,但是受本机内存限制。


整理自《深入理解java虚拟机》