内存管理和GC垃圾回收算法

71 阅读3分钟

认识内存管理

不管什么样的编程语言,在代码的执行过程中都是需要给它分配内存的,不同的是某些编程语言需要我们自己手动的管理内存,某些编程语言会自动帮助我们管理内存

不管以什么样的方式来管理内存,内存管理的生命周期包括以下三个步骤:

  1. 申请:分配所需的内存。
  2. 使用:将分配的内存用于存储数据(如对象等)。
  3. 释放:在内存不再需要时进行释放。

不同编程语言在内存管理的第一步(申请)和第三步(释放)的实现方式可以分为以下两类:

  1. 手动管理内存

    • 语言示例:C、C++、早期的Objective-C
    • 特点:开发者需手动调用函数(如 malloc 申请、free 释放)来管理内存。
  2. 自动管理内存

    • 语言示例:Java、JavaScript、Python、Swift、Dart
    • 特点:通过垃圾回收(GC)或自动引用计数(ARC)等机制自动处理内存释放,开发者无需手动干预。

Javascript在定义变量的时候会自动分配内存

内存分配方式是一样的吗?

  • JS对于基本数据类型内存的分配会在执行时,直接在栈空间进行分配;
  • JS对于复杂数据类型内存的分配会在堆内存中开辟一块空间,并且将这块空间的指针返回值变量引用;

image.png

JS的垃圾回收

因为内存的大小是有限的,所以当内存不再需要的时候,我们需要对其进行释放,以便腾出更多的内存空间。

在手动管理内存的语言中,我们需要通过一些方式自己来释放不再需要的内存,比如free函数:

  • 但是这种管理的方式其实非常的低效,影响我们编写逻辑的代码的效率;
  • 并且这种方式对开发者的要求也很高,并且一不小心就会产生内存泄露;

所以大部分现代的编程语言都是有自己的垃圾回收机制:

  • 垃圾回收的英文是Garbage Collection,简称GC;
  • 对于那些不再使用的对象,我们都称之为是垃圾,它需要被回收,以释放更多的内存空间;
  • 而我们的语言运行环境,比如Java的运行环境VM,JavaScript的运行环境js引擎都会内存 垃圾回收器
  • 垃圾回收器我们也会简称为GC,所以在很多地方你看到GC其实指的是垃圾回收器;

常见的GC算法-引用计数

  • 当一个对象有一个引用指向它时,那么这个对象的引用就+1,当一个对象的引用为0时,这个对象就可以被销毁掉;
  • 这个算法有一个很大的弊端就是会产生循环引用;

image.png 每多一个指向obj的,计数就会加一,如果不指向了,计数相应的会减一,当retain count=0的时候,会进行垃圾回收

**弊端:**循环引用

image.png 这样会产生内存泄漏

常见的GC算法-标记清除

  • 这个算法是设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于哪些没有引用到的对象,就认为是不可用的对象;
  • 这个算法可以很好的解决循环引用的问题; image.png 黄色的可达,不会回收,绿色的不可达,会垃圾回收