根据《Java虚拟机规范》JVM内存模型可以分为以下几个部分:

堆Heap、虚拟机栈VM Stack、方法区Method Area、本地方法栈Native Method Area、程序计数器Program Counter Register

下面用一段代码示例及图解展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Math {
public Math() {
}

public int compute() {
int a = 1;
int b = 2;
int c = (a + b) * 10;
return c;
}

public static void main(String[] args) {
Math math = new Math();
math.compute();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
命令:javap -c Math.class

Compiled from "Math.java"
public class com.canhuah.Math {
public com.canhuah.Math();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public int compute();
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: iconst_3
8: imul
9: istore_3
10: iload_3
11: ireturn

public static void main(java.lang.String[]);
Code:
0: new #2 // class com/canhuah/Math
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_1
8: aload_1
9: invokevirtual #4 // Method compute:()I
12: pop
13: return
}

https://img.cdn.canhuah.com/WX20220419_JVMM.png

堆(Java Heap/GC堆)

  • Eden+Survivor(s0+s1)+Old
  • 被所有线程共享的内存区域
  • new出来的对象
  • 可以使用jvisualvm命令查看

唯一目的就是存放对象实例,Java中”几乎“所有对象实例都在这里分配内存。《Java虚拟机规范》对此部分的描述:”所有 的对象实例以及数组都应当在堆上分配“。但是随着即时编译的技术发展,比如逃逸分析技术的日益强大,栈上分配 标量替换优化手段(会分配到方法栈),所以只能说”几乎“

虚拟机栈(Java Virtual Machine Stack/线程栈)

  • 线程私有
  • 方法在执行时会创建栈帧Stack Frame;用于存放 局部变量表、操作数栈、动态链接、方法出口

《Java虚拟机规范》对虚拟机栈区域规定了2类异常:如果线程请求的栈深度>虚拟机允许的深度,会抛出StackOverflow Error;如果栈容量可以动态扩展,且扩展到无法继续申请到足够内存,会抛出OOM异常(HotSpot虚拟机栈容量不可以动态扩展)

局部变量表

存放编译时确定的基本数据类型(boolean、byte、char、short、int、 float、long、double) 对象引用(reference 类型,不是对象本身,可能是指向对象起始地址的引用指针等) 和 return address

本地方法栈(Native Method Stacks)

  • native方法 c实现 作用与虚拟机栈相似

方法区(Method Area)

  • 常量+静态变量+类元信息

程序计数器(Program Counter Register)

相关面试题

  1. 方法区 和 永久代、元空间有什么区别?
    1. 方法区是理论(规范),接口
    2. 永久代、元空间是具体实现,实现类
      1. 永久代:在jdk7以前 堆区
      2. 元空间:jdk8开始 直接内存
      3. 为什么这么设计?
        1. gc的问题
        2. 应用的问题
        3. oom概率会更低
  2. jvm有几个虚拟机栈?
    1. 一个线程一个