JVM | 运行时数据区域

JVM | 运行时数据区域_第1张图片

1. 程序计数器

记录正在执行的虚拟机字节码指令的地址(如果正在执行的是本地方法则为空)。每条线程都需要一个独立的程序计数器。

2. Java虚拟机栈

JVM | 运行时数据区域_第2张图片
与程序计数器一样,Java 虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。

每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。

局部变量表所需内存空间在编译期间完成分配,存放了:

  1. 基本数据类型(boolean、byte、char、shrot、int、float、long、double)
  2. 对象引用(指向对象起始地址的引用指针)

两种异常:
StackOverflowError:线程请求栈深度大于虚拟机所允许深度
OutofMemoryError: 无法申请到足够空间

3. 本地方法栈

本地方法栈与 Java 虚拟机栈类似,它们之间的区别只不过是本地方法栈为本地方法服务。

4. Java 堆

是被所有线程共享的一块内存区域,所有对象都在这里分配内存,是垃圾收集的主要区域("GC 堆")。
异常 OutofMemoryError:Java堆中没有内存完成实例分配时抛出该异常。

5. 方法区

与Java堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。

对这块区域进行垃圾回收的主要目标是对常量池的回收和对类的卸载,但是一般比较难实现。

异常 OutofMemoryError:方法区无法满足新的内存分配要求时。

6. 运行时常量池

运行时常量池是方法区的一部分。

Class 文件中的常量池表(存放编译器生成的字面量和符号引用)会在类加载后被放入方法区的运行时常量池中。

动态性: 处理编译器产生常量,运行期间也可以将新的常量放入池中,例如String类的intern()方法.

异常 OutofMemoryError:收到方法区内存的限制,常量池无法再申请到内存时抛出该异常。

7. 直接内存

在 JDK 1.4 中新引入了 NIO 类,它可以使用 Native 函数库直接分配堆外内存,然后通过 Java 堆里的 DirectByteBuffer 对象作为这块内存的引用进行操作。这样能在一些场景中显著提高性能,因为避免了在堆内存(Java堆)和堆外内存(Native堆)来回拷贝数据。

异常 OutofMemoryError:本机直接内存的分配会受到本机总内存大小以及处理器寻址空间的限制。

参考资料

  1. https://github.com/CyC2018/CS...
  2. https://www.cnblogs.com/czwbi...

你可能感兴趣的:(jvm)