Java运行时数据区

Java运行时的数据区

  1. 方法区以及堆都是所有线程共享的数据区

  2. 其他都为线程隔离的数据区

  3. 除开程序计数器不会有OOM外,其他当申请不到需要的内存,或栈深度大于虚拟机栈深度都会抛出OutOfMemoryError或者StackOverflowError异常。

Method Area

  1. 方法区用来存放类型信息(类名、访问修饰符、方法描述等)、静态变量、常量、即时编译器编译后代码缓存数据。
  2. 方法区只是一个逻辑概念
    1. jdk1.8以前用 永久代(permanent Generation)实现,目的是为了让垃圾收集器像管理堆一样管理这部分内存,但是使用永久代更容易遇到内存溢出问题。
    2. jdk1.8以后使用在本地内存的元空间来实现方法区

Heap

  1. Java堆是虚拟机管理的最大一块内存,由所有线程共享,并虚拟机启动时创建。
  2. 堆中存放所有的对象实例和数组
  3. 从分配角度上看,所有线程共享的Java堆中可以划分出过个线程私有的分配缓冲区TLAB(Thread Local Allocation Buffer)。线程优先在自己私有的TLAB中分配对象,减少了线程竞争的消耗。

JVM Stacks

  1. 每个Java线程都有一个自己的JVM Stack, 每个栈里面存的都是栈帧,每个栈帧对应了一个方法,一个方法的调用开始与结束就是一个栈帧的入栈与出栈。

  2. 栈帧

    1. Local Variables:存放方法的局部变量
    2. Operand stacks:操作数栈
    3. Dynamic Linking:当创建对象、调用方法等需要获得引用时,会从Method Area的常量池中找到这个引用,并且看它是否从符号引用解析为直接引用,如果没有就直接解析,如果解析了就直接拿来用
    4. Return Address:当前栈帧所属的方法 A 中调用了方法 B,当调用完成后返回 A 时的返回值和此时A 应该从哪开始继续往下执行会记录在 Return Address中。

Native Method Stacks

  1. 本地方法栈与虚拟机栈作用相似,知识虚拟机栈为虚拟机执行Java方法即字节码服务,而本地方法栈为虚拟机使用本机方法即用C/C++或者其他语言写方法服务。

Program Counter Register

  1. 程序计数器是一块较小的内存,可以看作是当前线程所执行的字节码的行号指示器。字节码解释器的工作就是通过改变这个计数器的值来选取下一个需要执行的字节码指令,所以不会产生OOM
  2. 它是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等功能基础功能都需要依赖这个计数器来完成。
  3. 当时行的是本地Natvie方法时,计数器值为空
原文地址:https://www.cnblogs.com/zcr-xiaozhai/p/13827592.html