1.自动内存管理

自动内存管理其实指的是系统的垃圾回收(Garbage Collection):由程序语言运行时系统回收动态内存。

交由系统回收的好处是:

  • 避免手动内存管理,能够专注与实现业务逻辑

  • 保证内存的使用的正确性和安全性,避免出现如内存重复释放问题(double-free problem),内存释放后使用问题(use-after-free problem)

GC的主要三个任务:

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

相关概念

  • Mutator:业务线程,分配新对象,修改对象的指向关系
  • Collector:GC线程,找到存活对象,回收死亡对象的内存空间
  • Serial GC:串行GC,只有一个collector。这种回收方式在存在多个mutator时会暂停它们的线程,然后由一个collector进行回收
  • Parallel GC:并行GC,和串行类似,支持多个collectors同时回收的GC算法
  • Concurrent GC:mutator(s)和collector(s)可以同时执行

image.png

评价GC算法

我们可以通过以下几个方面来评价GC算法的好坏程度:

  • 安全性(Safety):不应回收存活的对象,这是最基本的要求

  • 吞吐率(Throughput):除开GC消耗时间后的运行时间与程序执行总时间的占比 ,这个占比越大越好
    $$
    1- \frac{GC时间}{程序执行总时间}
    $$

  • 暂停时间(Pause time):业务线程因为GC导致暂停的花费时间,这个时间越短越好

  • 内存开销(Space overhead):GC的元数据开销

追踪垃圾回收

通过根对象的引用链来标记可达对象使其不被回收,将其余不可达的对象视为垃圾进行回收清理。

常见的回收不可达对象有以下几种方法:

  • Copying GC:将存活对象复制到另外的内存空间,以便腾出一块连续的空闲内存
  • Mark-sweep GC:将死亡对象的内存标记为“可分配”(free),可以将需要内存的对象分配到free上
  • Mark-compact GC:移动并整理存活对象,将存活对象移动到一起,使得可以后面内存分配时可以紧接着前面的已分配内存地址。

分代GC

每个对象都可以根据其经历过的GC次数来划定其年龄,针对年轻和老年的对象指定不太的GC策略,以降低整体内存管理的开销。

  • 年轻代:由于年轻代中存活对象很少,可以采用copying GC
  • 老年代:对象趋于一直存活,反复进行复制开销较大,因此可以采用mark-sweep GC

引用计数

让每个对象都有一个与之关联的引用数目,对象存活的的条件使:当且仅当引用数大于0时

优点:内存管理的操作被平摊到程序执行的过程中(在新建或销毁对象时对应的引用数就会修改),并且内存管理不需要了解 runtime 的实现细节。

缺点:由于要维护每个对象的引用计数,所以维护开销较大,因为需要原子操作来保证对计数操作的原子性和可见性。另外也无法回收环形的数据结构。


  转载请注明: 流浪秃球计划

 上一篇
JVM JVM
一.JVM内存结构1.程序计数器 (Program Counter Register) 作用:记录下一条JVM指令的地址 Java源代码进行编译会被转化为二进制字节码(JVM指令) 虚拟机中的解释器负责把从程序计数器中得到的JVM指令
2023-01-30
下一篇 
线程并发 线程并发
一、进程:正在运行的程序。是程序的一次执行过程,或是正在运行的程序 二、线程进程的一个实体,一个进程可以拥有多个线程 单线程:同一个时刻,只允许执行一个线程 多线程:同一个时刻,允许执行多个线程 并发:同一时刻,多个任务交替执行,单核CPU
2022-12-23 Touko
  目录