自动内存管理| 青训营笔记

84 阅读2分钟

这是我参与「第五届青训营」笔记创作活动的第五天

自动内存管理

自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存

自动内存管理的三个任务:

  • 为新对象分配内存
  • 找到存活对象
  • 回收死亡对象的内存空间

相关概念

  • Mutator:业务线程,分配新对象,修改对象指向关系
  • Collector:GC线程,找到存活对象,回收死亡对象的内存空间
  • Serial GC:只有一个Collector
  • Parallel GC:支持多个Collertor同时回收
  • Concurrent GC:Mutator和Collector同时执行

Serial GC 和 Parallel GC 会发生Stop The World 暂停业务线程,Concurrent GC 不会发生暂停业务线程,业务线程和GC线程会一起执行

GC算法评价指标

  • 安全性
  • 吞吐率
  • 暂停时间
  • 内存开销

追踪垃圾回收算法

会维护对象的树形结构

被回收的条件:指针指向关系不可达的对象

步骤:

  • 标记根对象(如静态变量、全局变量、常量等)

  • 标记可达对象(从根对象出发,指针指向关系可达的对象)

  • 清理所有不可达对象

    清理算法:

    • Copy GC:将存活对象复制到另外的内存空间
    • Mark-Sweep GC:将死亡对象标记为可分配
    • Mark-compact GC:移动并整理存活对象

    根据对象的生命周期可以选择不同的标记和回收策略

引用计数算法

每个对象都有一个与之关联的引用数目,当引用数目大于0时,表明该对象时存活的,不能被回收,反之,可以被回收

优点:这样的GC算法可以被平坦到程序的执行当中,可以实现不会发生Stop The World

缺点:

  • 内存开销大:每个对象都需要额外的内存空间存储技术

  • 维护引用数目的开销比较大,需要通过原子操作保证对象引用数目正确

  • 很难处理环形数据结构——Weak Reference

  • 回收内存时依然可能发生暂停(回收大对象的时候还是会引发暂停)

分代GC思想

很多对象的生命周期很短暂,在分配之后就没有再使用了。也有一些对象生命周期很长,不管回收多少次都任然存活。

针对这种情况,提出了分代假说:

给对象设置年龄(年龄随着GC的次数增长),不同年龄的对象存活在不同的内存空间:

  • 年轻代:内存分配的区域,大多数对象的生命周期短暂,存活的对象很少,可以使用Copy GC
  • 老年代:由年轻代反复存活的对象复制而来,对象趋向于一直活着,可以使用Mark-Sweep GC