程序员鸡皮
文章 分类 评论
143 3 33

站点介绍

一名PHP全栈程序员的日常......

认识内存管理以及Javascript是如何进行垃圾回收的?

abzzp 2026-02-03 44 0条评论 前端 前端

首页 / 正文
本站是作为记录一名北漂程序员编程学习以及日常的博客,欢迎添加微信BmzhbjzhB咨询交流......

发布于2024-07-04

内存管理

在许多编程语言中都需要进行内存管理,有些是自动管理有些是手动管理,像我们的C和C++包括很老的OC,都是要手动管理来实现内存的管理的,然而我们大部分现代的语言基本都是自动回收和创建内存的,就比如我们的Java、JavaScript、Python、Swift、Dart等。

然而不管是手动管理还是自动管理内存都需要经历一下几个步骤:

  1. 第一步,申请分配内存
  2. 第二步,使用申请分配来的内存
  3. 第三步,当不用当前的内容之后,释放分配的内存。

对于Javascript语言来说,内存管理是自动的无形的,当我们创建变量,对象,类等都会使用到内存,但是不需要我们手动去管理内存,Javascript引擎就会像管家一样帮我们自动管理内存。

Javascript的垃圾回收

内存大小是有限的,这是由我们的设备决定的,当内存使用过高的时候就需要将不用的内存进行回收,以便腾出更多的空间使用。在手动管理内存的语言中,我们需要手动通过一些方式释放内存,比如free函数回收内存。

所以现在大部分编程语言都是要在使用过程中释放内存的,对于自动回收内存的语言来说都有自己的垃圾回收机制。垃圾回收的英文是Garbage Collection简称GC.对于不再使用的对象,我们称之为垃圾,需要被回收,比如Java语言JVM虚拟机会做垃圾自动回收,在我们Javascript中这件事情交给了Javascript引擎。在很多地方我们看到的GC通常说的就是垃圾回收器。

自动的垃圾回收器的优点就是,让我们更加关注逻辑代码的开发,提高了代码开发效率。这在处理大量数据或者管理复杂的数据结构的场景中尤为突出。

但是这里我们又提出了一个疑问,Javascript引擎如何知道哪些内存需要回收呢?

这里我们就要来聊一下GC的实现以及对应的算法。

GC的实现以及对应的算法

我们常见的GC算法有:引用计数,标记清除,还有其他的优化算法。下面我们一个一个说。

引用计数

引用计数垃圾回收(Reference Counting)中,每个对象都有一个关联的计数器。
当一个方法调用这个对象的时候,关联计数器就会相应的+1,如果还有另外一个方法调用该对象,也会进行+1操作,什么时候进行-1操作呢?就是我们函数或方法停止调用该对象的时候会进行-1操作,那么最后如果这个对象的关联计数器数值为0的时候,就会被GC算法清除。

打个比方,比如我们新创建了一个class类,然而全局都没有调用,在我们引用计数的GC算法眼里就会被直接清除。因为他的关联计数器显示的数值是0。

缺点

这个算法有一个很大的弊端就是会产生循环引用,当然我们可以通过一些方案,比如弱引用来解决(WeakMap就是弱引用)

打个比喻,如果说两个对象OneTwo,他两个之间相互调用。那么我们如何来解决这个缺点呢。就是我们需要在函数中定义One中对应在Two中调用的方法值设置为null就好了。

标记清除

标记清除算法
标记清除的核心思路是可达性,这个算法的核心思路是,设置一个根对象,从根对象开始查找如果有些对象是在根对象里面没有被引用的对象(不可达对象)。我们就看做成需要标记清除的对象。

我们的垃圾回收器会遍历所有根对象下的对象,发现不可达对象就将他们标记为垃圾,最终会进行回收流程。

优点
这个算法可以很好的解决引用计数算法中的循环引用问题。

其他优化算法

Javascript中比较广泛使用的是标记清除中的可达性算法,当然在V8引擎中也对他进行了优化。也会结合一些其他的算法。

标记整理(Mark-Compact)

和上面的标记清除算法类似,不同的是,回收期间同时会将保留的存储对象搬运汇集到连续的内存空间,从而整合空闲空间,避免内存碎片化

分代收集(Generational collection)

对象会被分为新的和旧的,许多对象出现,完成它们的工作并很快“死去”,它们可以很快被清理;那些长期存活的对象会变得“老旧”,而且被检查的频次也会减少;

增量收集(Incremental collection)
如果有许多对象,并且我们试图一次遍历并标记整个对象集,则可能需要一些时间,并在执行过程中带来明显的延迟。
Ø所以引擎试图将垃圾收集工作分成几部分来做(分解成多个小步骤或“增量”),然后将这几部分会逐一进行处理,这样会有许多微小的延迟而不是一个大的延迟;

闲时收集(Idle-time collection)

垃圾收集器只会在CPU 空闲时尝试运行,以减少可能对代码执行的影响。

感谢大家观看

评论(0)

文章目录

最新评论

  • abzzp

    @秋风于渭水 确实[[微笑]]

  • 通常会采取哪些措施来确保网站或者应用在不同的浏览器上的兼容性? - 程序员鸡皮-前端程序员|PHP程序员|全栈程序员

    [...]不同的浏览器存在兼容性问题的核心原因是不同的浏览器可能使用的是不同的浏览器内核。在现代化开发中,大多数的浏览器兼容性问题是可以通过工程化中的配置选项来解决的。1.比如browserslist可以配置目标的浏览器或者Node环境,然后在不同的工具中起作用,比如autoprefixer/babel/postess preset env等,在进行了正确的配置后,开发的Vue或者React项目在进行打包时[...]

  • BFC的作用是什么呢? - 程序员鸡皮-前端程序员|PHP程序员|全栈程序员

    [...]在BFC中,box会在垂直方向上一个挨着一个的排布垂直方向的间距由margin属性决定在同一个BFC中,相邻两个box之间的margin会折叠(collapse)在BFC中,每个元素的左边缘是紧挨着包含块的左边缘的然后我们再看一下官方文档中如何说明的?总结BFC是什么?W3C文档讲:在标准流中,我们所有的盒子,不管是块级盒子还是行内盒子,它们都属于某一个FC格式化上下文,块级盒子属于BFC`块级格[...]

  • 什么是FC呢?他是用来干什么的? - 程序员鸡皮-前端程序员|PHP程序员|全栈程序员

    [...]什么是FC呢这里我们给出W3C给出的文档,FC文档FC的全称是FormattingContext,元素在标准流里面都是属于一个FC的。那么什么又是IFC,BFC呢?IFC行内元素的布局都属于Inline Formatting,inline level box都是在IFC中布局的BFCBFC英文全称是Block Formatting Context,也就是block level box都是在BFC中[...]

  • 秋风于渭水

    这确实是一个盲点,这个还是很有必要的,处理不好会导致网页内的元素出现抖动问题。

  • defer属性在javascript标签中有什么作用? - 前端程序员,PHP程序员,全栈程序员-程序员鸡皮

    [...]我们知道,当浏览器在执行到script标签的时候,首先会停止构建DOM树,然后下载Javascript文件并且执行,当JavaScript脚本执行完毕之后才会继续解析HTML标签构建DOM树。为什么Javascript程序会这样做呢?原因是我们的Javascript的作用就是操作DOM并且可以修改DOM。如果我们等到HTML执行完成之后再去执行JavaScript就会造成严重的回流和重绘,尤其是现[...]

  • async属性是什么?它有什么作用? - 前端程序员,PHP程序员,全栈程序员-程序员鸡皮

    [...]async属性和defer属性目标一样它也是为了不让js阻塞DOM树的构建。不过他们两个还是有区别的。async让js脚本的下载和执行是独立的。浏览器不会因为async属性的script脚本的执行而阻塞,这一点和defer属性类似。然而async属性比较任性,只要脚本被浏览器下载完成之后就会立即执行,不会等待在DOMContentLoaded之前执行。所以它不能保证是在DOMContentLoad[...]

  • 城市教堂

    我热爱 旅游专栏。令人惊艳了解路线。

  • 湖山風光

    欣赏你的照片, 我明白, 世界很美。感谢 旅行灵感。

  • 古競技場

    读起来像小说。继续保持 带来的灵感。

日历

2026年03月

1234567
891011121314
15161718192021
22232425262728
293031    

站点公告
本站是作为记录一名北漂程序员编程学习以及日常的博客,欢迎添加微信BmzhbjzhB咨询交流......
点击小铃铛关闭
配色方案