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等方面),尤其是在频繁/周期性的逻辑中