JVM - 运行时数据区

运行时数据区

程序计数器
  ○ 程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。
  ○ 为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
Java虚拟机栈
  ○ 每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
  ○ 局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用。这些数据类型在局部变量表中的存储空间以局部变量槽(Slot)来表示。
  ○ 局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在栈帧中分配多大的局部变量空间是完全确定的,在方法运行期间不会改变局部变量表的大小。
  ○ OOM:当栈扩展时无法申请到足够的内存会抛出OutOfMemoryError异常
本地方法栈
  ○ 是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。
  ○ 在hotspot中,本地方法栈和Java虚拟机栈合并在一起
Java堆
  ○ Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例。
  ○ Java堆中存储内容的共性:无论是哪个区域,存储的都只能是对象的实例。
方法区
  ○ 方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。
  ○ 如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。
运行时常量池(Runtime Constant Pool)
  ○ 运行时常量池是方法区的一部分。
  ○ 常量池表(Constant Pool Table),用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。
  ○ 动态性:常量池分为静态常量池(class文件常量池)和运行时常量池。与class文件常量池相比,运行时常量池具有动态性,即运行期间也可以将常量加入常量池中。实现例子:String类下的intern()方法(用于加载常量到常量池)。
  ○ 运行时常量池受方法区内存限制,同样会出现OOM。
直接内存
  ○ NIO

 

参考资料:《深入理解Java虚拟机 第3版》 周志明

posted @ 2020-08-02 08:29  CofJus  阅读(78)  评论(0编辑  收藏  举报