JVM学习笔记——Java的内存区域

Java的内存区域

内存区域划分图

内存区域划分图

内存区域的特征

  • 方法区(Method Area)

    • 线程共享区域
    • 存储被虚拟机加载的类信息、常量、静态变量、编译后的代码等,又被称为Non-Heap,为堆的一个逻辑部分。在HotSpot虚拟机中,该区域也被作为永久代,但JDK1.7后的HotSpot中,已经将运行时常量池移出永久代。
    • 其中运行时常量池,具备动态性,运行期间也可以放入新的常量,例如String.intern()。
    • 内存无法满足需求时,抛出OOM(OutOfMemoryError)。
  • 虚拟机栈(VM Stack)

    • 线程私有,生命周期与线程相同
    • 描述Java方法执行的内存模型。每次调用方法就创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息;结束方法时栈帧就出栈。
      • 局部变量表存放基本数据类型与对象引用类型(指向对象的指针)
    • 请求的栈深度超出虚拟机允许的深度,抛出StackOverflowError;如果设定了动态扩展深度,扩展时申请不到内存,抛出OOM。
  • 本地方法栈(Native Method Stack)

    • 大部分特性与虚拟机栈类似,不同的是本地方法栈为native方法服务,在部分虚拟机中虚拟机栈会与本地方法栈合二为一。
  • 堆(heap)

    • 线程共享区域
    • 存放对象实例及数组,GC的主要区域;存储时处于物理上不连续的内存空间中;通过-Xmx和-Xms配置大小。
    • 堆无法扩展或没有内存完成实例分配时,抛出OOM
  • 程序计数器(Program Counter Register)

    • 线程私有
    • 当前线程所执行的字节码的行号指示器。执行普通方法时记录字节码指令地址;执行native方法时,则值为空(Undefined)。
  • 直接内存()

    • 直接内存不属于JVM规范中定义的内存区域,它是计算机的真实内存,在配置虚拟机参数时,经常会忽略直接内存,使得各个内存区域总合大于物理内存限制,从而导致OOM的发生。