• 学习网址
  • 网址的公众号:JavaGuide

随看随记

  • [栈与栈帧]
  • Java虚拟机栈–栈帧
  • java逃逸技术分析
  • TLAB对象创建
  • 详解 JVM Garbage First(G1) 垃圾收集器

运行时数据区域

程序计数器

  • 程序计数器主要有两个作用:(解释 + 保存)
  • 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
  • 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
  • 程序计数器是唯一一个不会出现 OutOfMemoryError 的内存区域,它的生命周期随着线程的创建而创建,随着线程的结束而死亡

Java 虚拟机栈

  • Java 内存可以粗糙的区分为堆内存(Heap)和栈内存 (Stack),其中栈就是现在说的虚拟机栈,或者说是虚拟机栈中局部变量表部分。 (实际上,Java 虚拟机栈是由一个个栈帧组成,而每个栈帧中都拥有:局部变量表、操作数栈、动态链接、方法出口信息。)
  • 局部变量表主要存放了编译期可知的各种数据类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型,它不同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)。
  • Java 虚拟机栈会出现两种错误:StackOverFlowError 和 OutOfMemoryError。
    1. StackOverFlowError: 若 Java 虚拟机栈的内存大小不允许动态扩展,那么当线程请求栈的深度超过当前 Java 虚拟机栈的最大深度的时候,就抛出 StackOverFlowError 错误。
    2. OutOfMemoryError: Java 虚拟机栈的内存大小可以动态扩展, 如果虚拟机在动态扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。

栈帧

  • 每个栈帧都存储着

    1. 局部变量表(Local Variables)
    2. 操作数栈(Operand Stack)(或表达式栈)
    3. 动态链接(Dynamic Linking)
    4. 方法返回地址(Return Adress)(或方法正常退出或者异常退出的定义)
    5. 一些附加信息
  • Java虚拟机栈中保存的主要内容是栈帧,每一次函数调用都会有一个对应的栈帧被压入 Java 栈,每一个函数调用结束后,都会有一个栈帧被弹出。
  • Java 方法有两种返回方式:
    1. return 语句。
    2. 抛出异常。
  • 不管哪种返回方式都会导致栈帧被弹出

本地方法栈

  • 和虚拟机栈所发挥的作用非常相似,区别是: 虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。
  • 本地方法被执行的时候,在本地方法栈也会创建一个栈帧,用于存放该本地方法的局部变量表、操作数栈、动态链接、出口信息。
  • 方法执行完毕后相应的栈帧也会出栈并释放内存空间,也会出现 StackOverFlowError 和 OutOfMemoryError 两种错误。