一、JVM 整体结构
![在这里插入图片描述](https://img-blog.csdnimg.cn/892dccf1510e4e67aaddb90f4ea1129d.png)
- JDK-1.8 前 永久代 或 持久代。
- JDK-1.8 元空间,常量、静态变量、类信息。
- 程序计数器(方法区存放的代码的内存地址,由字节码执行引擎变更)。
- 栈帧。
- 局部变量表。
- 操作数栈(临时值)。
- 动态链接(方法内部 引用 方法地址)。
- 方法出口。
- 本地方法栈。
二、JVM 内存模型
![在这里插入图片描述](https://img-blog.csdnimg.cn/e2d81a6bc84046e5900c89a1d5142a18.png)
三、JVM 内存参数
![在这里插入图片描述](https://img-blog.csdnimg.cn/c6f05e83c399403fb85f702e8c53d279.png)
- Spring Boot 程序的
java -jar xx.jar
启动脚本里。 - Tomcat 直接加在 bin目录 下 catalina.sh 脚本里。
java ‐jar qs‐server.jar \
‐Xms2048M \
‐Xmx2048M \
‐Xmn1024M \
‐Xss512K \
‐XX:MetaspaceSize=256M \
‐XX:MaxMetaspaceSize=256M
1. 栈溢出
public class StackOverflowErrorTest2 {
private static int count = 0;
@SuppressWarnings("all")
private static void redo() {
count++;
redo();
}
public static void main(String[] args) {
try {
redo();
} catch (Throwable t) {
t.printStackTrace();
System.out.println(count);
}
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/039da55bc7564949a854c01951279e5d.png)
四、逃逸分析
1. JVM 三种运行模式
- 解释模式(Interpreted Mode):
执行一行 JVM 字节码,就编译一行为 机器码。
只使用解释器(-Xint
强制 JVM 使用 解释模式)。 - 编译模式(Compiled Mode):
先将所有 JVM 字节码 依次编译为 机器码,然后一次性执行所有 机器码。
只使用编译器(-Xcomp
强制 JVM 使用 编译模式)。 - 混合模式(Mixed Mode):
依然一开始使用 解释模式 执行代码。
但是对于一些 热点代码 会采用 编译模式 执行。
编译的 热点代码 对应的 机器码 会被缓存起来,下次再执行无需再编译。
- 解释模式 启动快
对于只需要执行 部分代码,并且 大多数代码 只会 执行一次 的情况比较适合。 - 编译模式 启动慢,但后期执行速度快,而且比较占用内存
因为 机器码 的数量至少是 JVM字节码 的十倍以上,这种模式适合代码可能会被 反复执行 的场景。 - 混合模式 默认方式
这就是常见的 即时编译技术(JIT:Just In Time Compiler)。
在 即时编译 过程中,JVM 可能会对我们的代码做一些优化(比如:对象逃逸分析
等)。
2. 对象逃逸分析
- 对象逃逸分析:就是 分析对象动态作用域
当一个对象在方法中被定义后,它可能被外部方法所引用。
例如:作为 调用参数 传递到其他地方。
public class DoEscapeAnalysisTest {
public Person test() {
Person person = new Person();
person.setName("wy");
person.setAge(18);
return person;
}
public void test2() {
Person person = new Person();
person.setName("qs");
person.setAge(6);
System.out.println(person);
}
}