1. 内存模型
堆和栈的区别
-
栈是一种先入后出的数据结构;
栈是配合程序执行、配合函数调用用的;
栈存储的是程序执行时的临时数据。
-
堆不是一种数据结构,什么结构的数据都可以存放在堆中;
应用通过堆存储数据。
JVM的内存布局
-
线程独占:
- 栈(Stack)
- 本地方法栈(Native Method Stack)
- 程序计数栈(Program Counter Register)
-
线程共享:
- 堆(Heap)
- 方法区(Method Area)
JVM中Object都有哪些数据
JVM运行时数据都有哪些
JVM参数:
- 标准参数
- -X 扩展参数(非标准,不保证每个JVM都支持)
- -XX 开发用(比如打印详细日志)
2. 类加载
-
类加载流程
-
双亲委派机制
先委托给父类加载器执行,如果父类加载器还存在父类加载器,则继续向上委托,直到最顶层的加载器, 如果父类加载器能执行加载,则直接返回,如果父类加载器不能执行加载,则让子加载器自己去执行加载。
好处:1.避免类重复加载;2.避免java核心API被篡改
3. GC
-
STW:Stop The World,简称STW,指的是GC事件发生过程中,会产生应用程序的停顿。停顿产生时整个应用程序线程都会被暂停,没有任何响应。
-
Throughtput:吞吐量,指程序工作时间占比
-
FootPrint:内存使用,指最终应用对内存的需求
-
Latency:延迟,指GC造成的停顿(STW)时间
4. GC 算法
引用计数法(已被弃用)
引用计数法有什么问题:
- 无法解决循环引用问题
- 并发环境下,引用计数算错,没有纠错机制
Root Tracing
- 从根节点向下搜索连接,不连接的部分则为要回收的对象
3色标记清除算法
4. GC 工具
Serial Conllector
- 连续收集器,单线程,较老
- 算法:Root Tracing & Mark-Sweep
- -XX:+UseSerialGC
- 适用场景:
- 吞吐量小,内存回收工作量不大
- 可以容忍延迟,不在意卡顿
- 单核、内存小:0-100M
- 现在已经不用了
Parallel Collector
- 特点:提供最大的Throughtput,多线程
- 算法:Root Tracing & Mark-Sweep
- -XX:+UseParallelGC
- 适用场景:吞吐量要求大于延迟要求
- 现在已经不用了
CMS(Concurrent Mark Sweep)
- 减少暂停时间
- Mark/Sweep/Compact/Copy/等交替进行
- -XX:+UseConcurrentMarkSweepGC
- Minor VS Major
- Minor GC,回收新生代,JVM无法分配更多内存时触发
- Major GC,回收老生代
- Full GC,上面两个都进行回收
- 逐渐弃用
G1
- 特点:大内存,兼顾Latency和Throughtput
ZGC
- 低延迟,可以设置最大延迟时间
- 暂停时间不会随着堆大小、存活对象数目增加
graph LR
JVM --> A[内存模型]
A --> 程序计数器
A --> 方法区
A --> 堆
A --> 栈
A --> 本地方法栈
JVM --> B[类加载]
B --> 双亲委派机制
B --> Bootstrap类加载器
B --> Extension类加载器
B --> System类加载器
B --> 自定义类加载器
JVM --> C[GC]
C --> C1[分代回收]
C --> C2[回收器实现]
C1 --> 年轻代
C1 --> 老年代
C1 --> 持久代
C2 --> 串行回收器
C2 --> 并行回收器
C2 --> CMS
C2 --> G1
C2 --> ZGC
JVM --> D[编译器优化]
D --> 公共子表达式的消除
D --> 指令重排
D --> 内联
D --> D4[逃逸分析]
D4 --> 方法逃逸
D4 --> 线程逃逸
D --> 栈上分配
D --> 同步消除
JVM --> E[性能调优]
E --> JVM参数
E --> E2[性能分析工具]
E2 --> MAT
E2 --> JMC
E2 --> JStack
E2 --> JStat
JVM --> F[执行模式]
F --> 解释器模式
F --> 编译模式
F --> 混合模式