JVM进阶-JVM内存模型

1.内存模型图解

JVM进阶-JVM内存模型_第1张图片

2.常量池

常量池分为我们前面所说过的静态常量池,运行时常量池,还有字符串常量池,那么其实我们的运行时 常量池又是什么呢?

  1. 静态常量池

其实储存的就是字面量以及符号引用

  1. 运行时常量池

运行时常量池就是我们的每个类以及每个接口在我们的JVM进行run的过程中所在内存中开辟出来

的一块用来储存我们静态常量池部分数据的一块特殊区域。

  1. 字符串常量池

包含在动态常量池里

3. 方法区

  1. 方法区是各个线程共享的内存区域,在虚拟机启动时创建
  2. 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
  3. 当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常
  4. Java8 的时候又被元空间取代了,永久代和元空间都可以理解为方法区的落地实现。
  5. 方法区调整

DK1.8之前调节方法区大小:

-XX:PermSize=N //方法区(永久代)初始大小 -XX:MaxPermSize=N //方法区(永久代)最大大小,超出这个值将会抛出OutOfMemoryError

JDK1.8开始方法区

(HotSpot的永久代)被彻底删除了,取而代之的是元空间,元空间直接使用的是本机内存。参数设置:

-XX:MetaspaceSize=N //设置Metaspace的初始(和最小大小) -XX:MaxMetaspaceSize=N //设置Metaspace的最大大小

4.堆

  1. Java堆是Java虚拟机所管理内存中最大的一块,在虚拟机启动时创建,被所有线程共享。
  2. Java对象实例以及数组都在堆上分配。
  3. 在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口

5.虚拟机栈

  1. 虚拟机栈是一个线程执行的区域,保存着一个线程中方法的调用状态。换句话说,一个Java线程

的运行状态,由一个虚拟机栈来保存,所以虚拟机栈肯定是线程私有的,独有的,随着线程的创建而 创建。

  1. 每一个被线程执行的方法,为该栈中的栈帧,即每个方法对应一个栈帧。 调用一个方法,就会向栈中压入一个栈帧;一个方法调用完成,就会把该栈帧从栈中弹出。
  2. 每个栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向运行时常量池的引用(Areference to the run-time constant pool)、方法返回地址(Return Address)和附加信息。
  3. 示意图如下

JVM进阶-JVM内存模型_第2张图片

6.程序计数器

  1. 多线程在一个特定的时间段内只会执行其中某一个线程方法,CPU会不停的做任务切换,这样必然会导致经常中断或恢复。为了能够准确的记录各个线程正在执行的当前字节码指令地址,所以为每个线程都分配了一个PC寄存器,每个线程都独立计算,不会互相影响。
  2. 如果线程正在执行Java方法,则计数器记录的是正在执行的虚拟机字节码指令的地址;
  3. 如果正在执行的是Native方法,则这个计数器为空。

7.本地方法栈

  1. 如果当前线程执行的方法是Native类型的,这些方法就会在本地方法栈中执行。

8.即时编译器

参考:深入理解Java即时编译器(JIT)-上篇 - 知乎

你可能感兴趣的:(JVM,jvm,java,面试)