参考:
- 视频
- 书籍:《深入理解Java虚拟机-第3章 垃圾收集器与内存分配策略》
1.运行时数据区
1.1程序计数器
线程在执行Java方法:虚拟机字节码指令的地址
线程在执行Native方法:Undifined
唯一一个没有OutOfMemoryError的区域
1.2堆
存放对象和数组(数组也是对象)
OutOfMemoryError原因:创建的对象太多
1.3虚拟机栈
描述Java方法执行的内存模型(为字节码服务),每个方法在执行的时候都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
OutOfMemoryError原因:执行的方法太多
1.4本地方法栈
描述Native方法执行的内存模型,其他和虚拟机栈类似。
OutOfMemoryError原因:执行的方法太多
1.5方法区
已加载类的信息、常量、静态变量、即时编译后的代码
OutOfMemoryError原因:加载的类或常量等太多
2.判断对象已死的方法
2.1 引用计数法
无法解决对象循环引用的问题
2.2 可达性分析(首选)
2.3 引用分类
2.4 垃圾回收算法
2.4.1标记-清除算法
先逐个标记,再逐个清除垃圾。
缺点:效率不高,还产生大量的碎片。
2.4.1复制算法
每次使用一半的内存,用完一半时,把存活的对象复制到另一半区域,再对使用过的区域整体清理。
缺点:内存代价太高。
2.4.1标记-整理算法
先标记,再把活对象前移,最后把剩余的空间清理。
2.4.1分代搜集算法(首选)
Java堆分为新生代和老年代,根据各年代的生存周期选择合适的算法。
新生代:复制算法(多数死,少量活)
老年代:标记-清除和标记-清理。(少数死,多数活)
3. 垃圾收集器
3.1 Serial收集器
单线程,Stop The World
3.2 ParNew
多线程,Stop The World
3.3 Parallel Scavenge
新生代收集器,复制算法,并行的多线程收集器
特点是自调节策略,可控制垃圾处理的时间
3.4 Serial Old
Serial的老年代版本,单线程,标记整理算法
3.5 Parallel Old
Parallel Scavenge的老年版本
3.5 CMS收集器