JVM学习笔记——java内存区域与内存溢出异常

JVM学习笔记——java内存区域与内存溢出异常

    • java内存区域
      • 程序计数器
      • Java虚拟机栈
      • 本地方法栈
      • Java堆
      • 方法区

学习《深入理解Java虚拟机:JVM高级特性与最佳实践》的笔记。

java内存区域

程序计数器

程序计数器是一块较小的内存空间,可以看做是当前线程执行字节码的行号指示器。为保证每次线程切换过程中,都会恢复到该线程正确的位置,每条线程都需要一个程序计数器。因此,程序计数器是线程私有的。

Java虚拟机栈

Java虚拟机栈,虚拟接栈描述的是java方法执行的线程内存模型:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方发出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
虚拟机栈是线程私有的,生命周期与对应线程相同。
局部变量表用于存放编译期可知的各种Java基本数据类型、对象引用、returnAddress类型。
异常

  1. 当线程请求的栈深度大于虚拟机所允许的栈深度时,抛出Stack OverflowError异常。
  2. 如果虚拟机栈容量可以动态扩展,当栈扩展时无法申请到足够内存时,会抛出OutOfMemoryError异常。
    :HotSpot虚拟机的栈容量是不可以动态扩展的,因此不会由于无法扩展而抛出OutOfMemoryError异常,但如果申请时就失败,仍然会有OOM异常。

本地方法栈

本地方法栈虚拟机栈所发挥的作用非常相似,其区别是指虚拟机栈为虚拟机执行Java方法,而本地方法栈则是为虚拟机使用到的本地方法服务。

  1. HotSpot虚拟机直接把本地方法栈与虚拟机栈合二为一。
  2. 本地方法栈与虚拟机栈一样,会抛出Stack OverflowError异常和OutOfMemoryError异常。

Java堆

Java堆唯一的作用就是用来存放对象实例,是所有线程共享的一块内存区域。Java中的垃圾收集器便是用来管理这一块内存的。关于这一区域的详细介绍,会在后续的垃圾回收机制中提及。
异常:Java堆可被设置为固定大小或者是可扩展的(通过参数-Xmx和-Xms设定),当Java堆无法完成实例内存分配,堆也无法扩展时,抛出OutOfMemoryError异常。

方法区

方法区也是线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量等数据。
运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量与符号引用,这部分数据在类加载后存放到方法区的运行时常量池中。
异常:常量池无法申请到内存时,抛出OutOfMemoryError异常。

你可能感兴趣的:(JVM学习笔记)