# 深入理解Java虚拟机 JVM高级特性与最佳实践
# 第三章 垃圾收集器与内存分配策略
## GC需要完成的3件事情
1. 哪些内存需要回收
2. 什么时候回收
3. 如何回收
## 需要回收的内存区域
```
程序计数器、栈、本地方法栈3个区域随线程而生,随线程而灭,所以不需要进行垃圾回收。
程序处于运行期间才知道会创建哪些对象,java堆上的内存分配是动态分配的,所以收集器关注
的是这部分内存。
```
## 判断对象可回收的算法
1. 引用计数法
```
这个算法解决不了对象循环引用问题,所以java没有采用此种算法。
```
2. 可达性算法
```
这个算法基本思路是通过一系列称为"GC Roots"的对象为起始点,从这些节点开始向下搜索,搜索的路径称为引用链,
当一个对象没有任何引用链相连,则证明此对象不可用,可以被回收。
可作为GC Roots的对象包括下面几种:
1. 栈中引用的对象
2. 方法区中类静态属性引用的对象
3. 方法区中常量引用对象
4. 本地方法栈中JNI引用的对象
```
## 对象死亡之前的"挣扎"
```
要真正宣告一个对象死亡,至少要经历两次标记过程,如果对象没有相连接的引用链,那它会被第一次
标记并且进行一次筛选,筛选的条件是些对象是否有必要执行finalize()方法。当对象没有覆盖finalize()
方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况视为没必要执行,直接回收。
但不鼓励使用finalize()方法。
```
## 垃圾收集算法
* 标记-清除算法
```
此算法分为标记和清除两个阶段。
首先标记出所以需要回收的对象,然后统一回收所有被标记的对象。
缺点:
1. 效率不高
2. 收集完成后产生的内存碎片太多
```
* 复制算法
```
它将可用内存按容量划分为大小相等的两块,每次只使用其中一块。当一块内存用完了,就
将还存活着的对象复制到另外一块上面,然后清除掉使用过的内存空间。
缺点:
1. 使用内存被缩小了一半
2. 复制的对象过多过大耗时严重
优点:
1. 不会产生内存碎片
```
* 标记-整理算法
```
标记整理与标记清除相似,标记整理只是标记后,让所以存活的对象都向一端移动,然后
直接清理掉端边界以外的内存。
```
* 分代收集算法
```
当前的商业虚拟机的垃圾收集器都采用分代收集算法。一般是把java堆分为新生代和老年代,
这样可以根据各个年代的特点采用最适当的收集算法。
在新生代中,每次垃圾收集时都有大量对象死去,那就选用复制算法,只需要付出少量存活
对象复制成本就可以完成收集。面老年代中因为存活率高,就必须使用标记-清理或标记整理
来回收。
```
## 吞吐量
```
所谓吞吐量就是CPU用于运行用户代码的时候与CPU总消耗时间的比值,
即吞吐量=运行用户代码时间 / (运行用户代码时间+垃圾收集时间)
虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%
```
## Minor GC与Full GC
* 新生代 GC(Minor GC)
```
Minor GC指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常
频繁,一般回收速度也比较快。
```
* 老年代 GC(Major GC/Full GC)
```
指发生在老年代的GC,出现了Major GC,经常会伴随至少一次的Minor GC.
Major GC的速度一般会比Minor GC慢10倍以上。
```
## 内存分配与回收策略
* 对象优先在Eden分配
```
大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一
次Minor GC。
```
* 大对象直接进入老年代
```
所谓的大对象是指,需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串
以及数组。
```
* 长期存活的对象将进入老年代
```
虚拟机给每个对象定义了一个对象年龄计数器。如果对象在Eden出生并经过第一次Minor GC后仍
锛存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1.对象在Survivor
区中每"熬过"一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁),就将被晋升到
老年代中。
```
* 动态对象年龄判定
```
为了能更好地适应不同程序的内存状况,虚拟机并不是永远地要求对象的年龄必须达到MaxTenuringThreshold
才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或
等于该年龄的对象就可以直接进入老年代,无须等到MaxTenuringThreshold中要求的年龄。
```
* 空间分配担保
```
在发生Minor GC前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个
条件成立,那么Minor GC可以确保是安全的。
如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会
继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,
尽管这次Minor GC有风险的。
如果小于,并且设置HandlePromotionFailure不允许冒险,那这时也要改为进行一次Full GC.
```
baidu_16992441
- 粉丝: 311
- 资源: 1041
最新资源
- 3.5Ni钢焊接接头经不同加热冷却后组织和性能的变化.pdf
- 3R60UG尿素级不锈钢的焊接工艺评定 - .pdf
- 3轴联动数控焊接机设计研究.pdf
- 04SG309 钢筋焊接网混凝土楼板与剪力墙构造详图.pdf
- 脑肿瘤医学影像数据集,脑部肿瘤图像数据集,脑部癌症图像数据集
- 基于java+springboot+mysql+微信小程序的小微金融企业系统 源码+数据库+论文(高分毕业设计).zip
- 基于java+springboot+mysql+微信小程序的小区服务管理系统 源码+数据库+论文(高分毕业设计).zip
- 基于java+springboot+mysql+微信小程序的小区物业新冠疫情物资管理平台 源码+数据库+论文(高分毕业设计).zip
- 基于java+springboot+mysql+微信小程序的小演员招募小程序 源码+数据库+论文(高分毕业设计).zip
- 基于java+springboot+mysql+微信小程序的校园心声墙小程序 源码+数据库+论文(高分毕业设计).zip
- 飞轮储能充放电控制simulink仿真模型,采用永磁同步电机 充电过程外环控制转速,内环控制dq轴电流; 放电过程外环控制直流母线电压,内环控制dq轴电流 整体都采用矢量控制、dq轴解耦控制,跟随
- 基于java+springboot+mysql+微信小程序的校园生活服务系统 源码+数据库+论文(高分毕业设计).zip
- 基于Python的简易天气预报系统开发项目
- Masked LM 完整使用介绍及代码解释
- 基于java+springboot+mysql+微信小程序的校园选课小程序 源码+数据库+论文(高分毕业设计).zip
- 基于java+springboot+mysql+微信小程序的中医知源小程序 源码+数据库+论文(高分毕业设计).zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈