(一)JVM内存管理

为什么要了解JVM的内存区域??

因为JAVA最引以为豪的就是自动内存管理机制。相比较于C++手动管理内存,复杂的指针处理,JAVA使用更方便。这就是有点也是缺点(对于内存极其敏感的程序难以控制内存管理)。

JVM 内存区域划分如图所示,从图中我们可以看出:

  •     JVM 堆中的数据是共享的,是占用内存最大的一块区域。
  •     可以执行字节码的模块叫作执行引擎。
  •     执行引擎在线程切换时怎么恢复?依靠的就是程序计数器。
  •     JVM 的内存划分与多线程是息息相关的。像我们程序中运行时用到的栈,以及本地方法栈,它们的维度都是线程。
  •     本地内存包含元数据区和一些直接内存。

五大区域:本地方法栈,JAVA虚拟机栈,程序计数器,堆,方法区

虚拟机栈

JAVA虚拟机栈是基于线程的,哪怕只有一个main方法也是以线程的方式运行的。在线程的生命周期中,参与计算的数据会频繁的入栈和出栈。

栈里面的每条数据就是栈帧。在每个java方法被调用的时候都会创建一个栈帧并入栈。一旦完成相应的调用就会出站,当线程中不存在栈帧的时候线程也就结束了。

每个栈帧包含四个区域:

  • 局部变量表
  • 操作数栈
  • 动态连接
  • 返回地址

本地方法栈

和虚拟机栈非常相似,不过他的服务对象是

native方法这里有一个比较特殊的数据类型叫作 returnAdress。因为这种类型只存在于字节码层面,所以我们平常打交道的比较少。对于 JVM 来说,程序就是存储在方法区的字节码指令,而 returnAddress 类型的值就是指向特定指令内存地址的指针。

  • 这里有一个两层的栈。第一层是栈帧,对应着方法;第二层是方法的执行,对应着操作数。注意千万不要搞混了。
  • 你可以看到,所有的字节码指令,其实都会抽象成对栈的入栈出栈操作。执行引擎只需要傻瓜式的按顺序执行,就可以保证它的正确性

程序计数器

程序计数器是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器

可以看到,程序计数器也是因为线程而产生的,与虚拟机栈配合完成计算操作。程序计数器还存储了当前正在运行的流程,包括正在执行的指令、跳转、分支、循环、异常处理等。

堆是 JVM 上最大的内存区域,我们申请的几乎所有的对象,都是在这里存储的。我们常说的垃圾回收,操作的对象就是堆。

元空间

回想一下类与对象的区别。对象是一个活生生的个体,可以参与到程序的运行中;类更像是一个模版,定义了一系列属性和操作。

那么问题来了类的元数据存在哪里呢?JAVA8之后就在元空间了

存储的内容,包括:类的信息、常量池、方法数据、方法代码

元空间的好处:使用非堆可以使用操作系统的内存,不会再出现方法区的内存溢出了

元空间的坏处:无限制使用会造成操作系统的死亡。不过可以用-XX:MaxMetaspaceSize 参数控制大小

猜你喜欢

转载自blog.csdn.net/lss446937072/article/details/109848561
今日推荐