1. JVM的结构
- 类加载器:bootstrapClassLoader、ExtClassLoader、AppClassLoader
- 运行时数据区:
-
- 方法区:存储已被虚拟机加载的类、接口、类中方法字节码、类中字段,静态变量,常量,运行时常量池
- 堆:存放对象实例
- java栈:
- 程序计数器:当前线程所执行的字节码的行号指示器
- 本地方法栈:虚拟机使用到的Native方法服务
- 执行引擎(Execution Engine):解析执行class文件中的指令
- 本地方法接口:
2. 栈帧存储什么
- 栈帧数据(Frame Data):方法信息
- 本地变量(Local Variables):输入参数、输出参数、方法内的变量(8种基本类型的变量+对象的引用变量)
- 栈操作(Operand Stack):记录出栈、入栈的操作(方法的调用过程就是入栈出栈的过程)
3. 双亲委派模型
- 当APPClassLoader加载一个class时,先把类加载请求委派给父类加载器ExtClassLoader去完成
- 当ExtClassLoader加载一个class时,先把类加载请求委派给父类加载器BootStrapClassLoader去完成
- 如果BootStrapClassLoader加载失败,会使用ExtClassLoader来加载
- 如果ExtClassLoader加载失败,会使用AppClassLoader来加载
- 如果AppClassLoader也加载失败,则会报异常ClassNotFoundException
4. 堆的构成
- 新生区:
-
- 伊甸区(Eden space):
- 幸存者区(Survivor space):
- 老年代
- 永久代
5.常见JVM参数
- xms:初始堆大小,默认是内存的1/64
- xmx:最大堆的大小,默认是内存的1/4
- xmn:新生区的大小
- xx:+pringGCDetails:输出详细的GC处理日志
6. 垃圾判定的方法
- 引用计数法:通过判断对象的引用数量来决定对象是否可以被回收
- 可达性分析法:从"GC Roots"节点开始向下搜索,节点所走过的路径称为引用链,引用链不包含的对象即可以回收的对象
-
- 栈帧中的本地变量表中的引用对象
- 方法区中的类静态属性引用的对象
- 方法区中的常量引用的对象
- 本地方法栈中JNI的 引用对象
7. 四种引用
- 强引用:永远不会被垃圾回收器回收
- 软引用:内存不足时会被垃圾回收器回收
- 弱引用:下次垃圾回收时会被垃圾收集器回收
- 虚引用:无法通过虚引用获取对象实例,在引用的对象被垃圾收集器回收时会收到通知
8. 垃圾回收算法
- 复制算法:将内存平均分成两部分,将这部分满的内存中的存活对象复制到另一个内存中,然后将这个内存进行清空处理
-
- 优点:实现简单、不产生内存碎片
- 缺点:浪费内存
- 标记清除算法:使用可达性分析算法标记出需要回收的对象,将标记的对象进行清除
-
- 优点:不会浪费内存
- 缺点:内存空间不连续
- 标记整理算法:使用可达性算法标记出存活对象和垃圾对象,将存活对象移动到一端,然后清除边界外的内存
9. 垃圾收集器:
- Serial收集器:垃圾收集的过程会STW
-
- 区域:新生代
- 算法:复制算法
- 线程:单线程
- 类型:串行
- ParNew收集器:Serial的多线程版本
-
- 新生代:复制算法、并行
- 老年代:标记整理、串行
- Parallel收集器:关注系统的吞吐量
-
- 区域:新生代
- 算法:复制算法
- 线程:多线程
- 类型:并行
- Serial Old收集器:
-
- 区域:老年代
- 算法:标记整理
- 线程:单线程
- 类型:串行
- Parallel Old收集器:
-
- 区域:老年代
- 算法:标记整理
- 线程:多线程
- 类型:并行
- CMS收集器:关注系统的响应时间
-
- 区域:老年代
- 算法:标记清除
- 线程:多线程
- 类型:并行
- 过程
-
-
- 初始标记:只标记GCRoot,stw
- 并发标记:工作线程正常执行,标记垃圾对象
- 重新标记:标记垃圾对象,stw
- 并发清除:可以和用户线程同时执行,清除垃圾对象
-
- G1收集器:面向服务端应用,针对多核CPU及大容量内存,JDK9之后默认的垃圾收集器
-
- 特点:
-
-
- 空间整合
- 可预测停顿
-
10. 垃圾回收器选择策略
- 客户端程序:Serial + Serial Old
- 吞吐率优先的服务端程序 : Parallel Scavenge + Parallel Old;
- 响应时间优先的服务端程序 :ParNew + CMS