Java高级特性之垃圾回收-粗糙版
垃圾回收介绍
jvm内存管理
什么是垃圾回收(Garbage Collection)
- 把不用的内存回收掉
- java采用自动内存管理技术,内存分配后由虚拟机自动管理
优缺点:
- 优点:程序员不需要自己释放内存,只管new对象即可
- 缺点:GC本身有开销,会挤占业务执行资源。
什么是垃圾:
- 不会被访问到的对象是垃圾
引用计数法
原理
- 记录每个对象被引用的数量,当被引用的数量为0时,则标记为垃圾
- 缺点:无法处理循环引用的问题
可达性分析
原理
- 从GC Roots开始遍历对象,没有被遍历到的对象为垃圾
GC Roots:
- 方法栈使用到的参数、局部变量、临时变量等
- 方法区中类静态属性引用的变量
- 方法区中常量引用的对象
- 本地方法栈中JNI引用的对象
垃圾回收算法
清除(sweep)
原理
- 将垃圾对象所占据的内存标记为空闲内存,然后存在一个空闲列表(free list)中。当需要创建对象时,从空闲列表中寻找空闲内存,分配给新创建的对象
优缺点:
- 优点:速度快
- 缺点:容易造成内存碎片,分配效率低
整理(compact)
原理
- 把存活的对象搬到内存的起始位置,然后在连续的空间内顺序分配
优缺点:
- 优点:分配速度快,局部性好
- 缺点:搬运对象麻烦,性能开销大
复制(copy)
原理
- 将内存分为两个部分,并分别用from和to指针来维护。每次只在from指向的内存中分配内存,当发生垃圾回收时,将from指向区域中存活的对象复制到to指向的内存区域,然后将from指针和to指针互换位置。
优缺点:
- 优点:同压缩算法,没有内存碎片。分配速度快,局部性好
- 缺点:可用内存变少,堆空间使用效率低
垃圾收集器
jvm堆划分
jvm将堆划分为新生代和老年代。新生代存放新创建的对象,当对象生存超过一定时间时,会被移动至老年代。新生代采用的 GC 称为minor GC,老年代发生的 GC 称为 full GC 或 major GC,发生full GC会伴随至少一次minor GC
Minor GC
特点:发生次数多,采用时间短,回收掉大量对象
收集器:serial, Parallel Scavenge, Parallel New.均采用复制算法. Serial是单线程,Parallel New可以看成Serial多线程版本. Parallel Scanvenge和Parallel New类似,但更注重吞吐率,且不能与CMS一起使用
Full GC
特点:发生次数少,耗时长
收集器:Serial Old(整理), Parallel Old(整理), CMS(清除). Serial Old是单线程的,Parallel Old可以看成Serial Old的多线程版本. CMS是并发收集器,除了初始标记和重新标记操作需要Stop the world,其它时间可以与应用程序一起并发执行
垃圾回收触发条件
Minor GC
- Eden区空间不足
Full GC
- 老年代空间不足
- 方法区(Metaspace)空间不足
- 通过minor GC进入老年代的平均大小大于老年代的可用内存
- 老年代被写满
- 调用System.GC,系统建议执行full GC,但不一定执行。 《华为Java语言通用编程规范》规则8.7.5:禁止使用主动GC(除非在密码、RMI等方面),尤其是在频繁/周期性的逻辑中