理解垃圾回收和闭包| 青训营笔记

64 阅读3分钟

在JavaScript中,垃圾回收(Garbage Collection,GC)是自动执行的进程,它负责检测和清除不再被程序使用的对象和变量,以释放内存空间。

在JavaScript中,垃圾回收器通常使用两种策略来检测不再使用的对象:引用计数和标记-清除。

新生代区域(1M-8M)垃圾回收采用引用计数是一种简单的技术,它跟踪对象的引用次数。每当一个对象被引用时,引用计数器就会增加1,每当一个引用被取消时,引用计数器就会减少1。当一个对象的引用计数器降至零时,它就可以被垃圾回收器清除。

1.垃圾标记

2.对象复制

3.区域翻转

老生代区域垃圾回收采用标记-清除算法使用一种更复杂的技术来检测不再使用的对象。这个算法首先标记所有当前被引用的对象,然后清除未被标记的对象。这种算法能够处理复杂的数据结构,但也需要更多的计算资源。

在JavaScript中,闭包是指在函数内部创建另一个函数,并将其作为返回值返回,从而形成了一个封闭的作用域。这个封闭的作用域可以访问在其外部定义的变量和参数,即使外部函数已经返回并结束执行,闭包仍然可以访问这些变量和参数。

闭包在JavaScript中非常常见,它可以用来实现很多高级的编程技巧,比如封装、模块化、函数式编程等。闭包也可以帮助我们避免使用全局变量,从而提高代码的可维护性和可读性。

下面是一个简单的闭包示例,其中函数inner被定义在函数outer内部,并返回了一个函数。在返回的函数中,它可以访问外部函数outer中定义的变量x和参数y:

function outer(x) {
  function inner(y) {
    return x + y;
  }
  return inner;
}

var addFive = outer(5);
console.log(addFive(3)); // 输出 8

在这个示例中,outer函数返回了inner函数,我们将这个返回的函数存储在变量addFive中,并调用它来计算5和3的和。由于inner函数形成了一个闭包,它可以访问外部函数outer中定义的变量x,所以在调用addFive(3)时,它返回了8。

需要注意的是,闭包可能会导致内存泄漏,因为闭包中的变量不会被垃圾回收器自动释放。因此,在使用闭包时,我们应该注意避免在闭包中引用过多的外部变量,尤其是对象和函数。

在Java中,垃圾回收(Garbage Collection,GC)是自动执行的进程,它负责检测和清除不再被程序使用的对象和变量,以释放内存空间。Java中的垃圾回收器使用了一种称为“标记-清除”算法的技术来检测和清除垃圾对象。

标记-清除算法分为两个阶段:

  1. 标记阶段:垃圾回收器会遍历所有的存活对象,并在它们的头部打上标记。这个过程类似于寻找图中的所有节点,找到所有的可达对象。
  2. 清除阶段:垃圾回收器会清除没有被标记的对象,并回收它们所占用的内存空间。这个过程类似于删除图中的所有未被访问到的节点。

Java中的垃圾回收器是自动执行的,程序员不需要显式地释放内存。但是,Java中的垃圾回收器并不是实时执行的,它需要在一定的时间间隔内扫描堆内存,因此在Java中存在一定的内存占用和性能开销。