0

0

javascript有gc吗

青灯夜游

青灯夜游

发布时间:2021-10-09 16:55:33

|

3113人浏览过

|

来源于php中文网

原创

javascript中有GC(垃圾回收机制)。JavaScript是使用垃圾回收机制的语言,执行环境负责在代码执行时管理内存,会自动将垃圾对象(没有被引用的对象)从内存中销毁。

javascript有gc吗

本教程操作环境:windows7系统、javascript1.8.5版、Dell G3电脑。

JavaScript 中的垃圾回收机制(GC)

垃圾回收相关概念

① 什么是垃圾

没有被使用(引用)的对象就是垃圾

立即学习Java免费学习笔记(深入)”;

② 什么是垃圾回收

没有被引用的对象被销毁,内存被释放,就是垃圾回收

C、C++ 等编程语言需要手动垃圾回收。

Java、JavaScript、PHP、Python 等语言自动垃圾回收。

JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要也不能进行垃圾回收的操作。我们需要做的只是要将不再使用的对象设置为 null 即可。

为什么需要垃圾回收

  • 在C / C++中,跟踪内存的使用和管理内存对开发者来说是很大的负担
    • JavaScript是使用垃圾回收机制的语言,也就是说执行环境负责在代码执行时管理内存,帮开发者卸下了这个负担
    • 通过自动内存管理实现内存的分配和资源的回收
    • 基本思路很简单,确定哪个变量不会再被使用了,把它的内存空间释放
    • 这个过程是周期性的,意思是这个垃圾回收程序每隔一段时间就会运行一次
  • 像JS中的对象、字符串、对象的内存是不固定的,只有真正用到的时候才会动态分配内存
    • 这些内存需在不使用后进行释放以便再次使用,否则在计算机可用内存耗尽后造成崩溃
  • 浏览器发展史上的垃圾回收法主要有
    • 引用计数法
    • 标记清除法

引用计数法

思路

  • 变量只是对值进行引用
  • 当变量引用该值时,引用次数+1
  • 当该变量的引用被覆盖或者清除时,引用次数-1
  • 当引用次数为0时,就可以安全地释放这块内存。
let arr = [1, 0, 1]   // [1, 0, 1]这块内存被arr引用  引用次数为1
arr = [0, 1, 0]  // [1, 0, 1]的内存引用次数为0被释放  
                 // [0, 1, 0]的内存被arr引用   引用次数为1
const tmp = arr  // [0, 1, 0]的内存被tmp引用   引用次数为2

循环引用问题

Netscape Navigator 3.0 采用

  • 在这个例子中,ObjectA和ObjectB的属性分别相互引用
  • 造成这个函数执行后,Object被引用的次数不会变成0,影响了正常的GC。
  • 如果执行多次,将造成严重的内存泄漏。
  • 而标记清除法则不会出现这个问题。
function Example(){

    let ObjectA = new Object();
    let ObjectB = new Object();

    ObjectA.p = ObjectB;
    ObjectB.p = ObjectA;   

}

Example();
  • 解决方法:在函数结束时将其指向null
ObjectA = null;
ObjectB = null;

标记清除法

为了解决循环引用造成的内存泄漏问题,Netscape Navigator 4.0 开始采用标记清除法

到了 2008 年,IE、Firefox、Opera、Chrome 和 Safari 都在自己的 JavaScript 实现中采用标记清理(或 其变体),只是在运行垃圾回收的频率上有所差异。

思路

  • 在变量进入执行上下文时打上“进入”标记
  • 同时在变量离开执行上下文时也打上“离开”标记
    • 从此以后,无法访问这个变量
    • 在下一次垃圾回收时进行内存的释放
function Example(n){
    const a = 1, b = 2, c = 3;
    return n * a * b * c;
}
// 标记Example进入执行上下文

const n = 1;  // 标记n进入执行上下文
Example(n);   // 标记a,b,c进入执行上下文
console.log(n); // 标记a, b, c离开执行上下文,等待垃圾回收

const和let声明提升性能

  • const和let不仅有助于改善代码风格,同时有利于垃圾回收性能的提升
  • const和let使JS有了块级作用域,当块级作用域比函数作用域更早结束时,垃圾回收程序更早介入
  • 尽早回收该回收的内存,提升了垃圾回收的性能

V8引擎的垃圾回收

V8引擎的垃圾回收采用标记清除法与分代回收法

分为新生代和老生代

新生代

新生代垃圾回收采用Scavenge 算法

分配给常用内存和新分配的小量内存

  • 内存大小

    • 32位系统16M内存
    • 64位系统32M内存
  • 分区

    • 新生代内存分为以下两区,内存各占一半
    • From space
    • To space
  • 运行

    Asp+Ajax(Jquery)实用例子
    Asp+Ajax(Jquery)实用例子

    Ajax是目前比较流行的网站建设技术,尤其作为网站建设者来说,掌握它十分有必要,如果用原生Javascript开发则比较困难,还好有强大的Jquery加持,开发则变的十分简单和容易。

    下载
    • 实际运行的只有From space
    • To space处于空闲状态
  • Scavenge算法

    • 当From space内存使用将要达到上限时开始垃圾回收,将From space中的不可达对象都打上标记
    • 将From space的未标记对象复制到To space。
      • 解决了内存散落分块的问题(不连续的内存空间)
      • 相当于用空间换时间。
    • 然后清空From space、将其闲置,也就是转变为To space,俗称反转。
  • 新生代 -> 老生代

    • 新生代存放的是新分配的小量内存,如果达到以下条件中的一个,将被分配至老生代
      • 内存大小达到From space的25%
      • 经历了From space To space的一个轮回

img

老生代

老生代采用mark-sweep标记清除和mark-compact标记整理

通常存放较大的内存块和从新生代分配过来的内存块

  • 内存大小
    • 32位系统700M左右
    • 64位系统1.4G左右
  • 分区
    • Old Object Space
      • 字面的老生代,存放的是新生代分配过来的内存。
    • Large Object Space
      • 存放其他区域放不下的较大的内存,基本都超过1M
    • Map Space
      • 存放存储对象的映射关系
    • Code Space
      • 存储编译后的代码
  • 回收流程
    • 标记分类(三色标记)
      • 未被扫描,可回收,下面简称1类
      • 扫描中,不可回收,下面简称2类
      • 扫描完成,不可回收,下面简称3类
    • 遍历
      • 采用深度优先遍历,遍历每个对象。
      • 首先将非根部对象全部标记为1类,然后进行深度优先遍历。
      • 遍历过程中将对象压入栈,这个过程中对象被标记为2类
      • 遍历完成对象出栈,这个对象被标记为3类
      • 整个过程直至栈空
    • Mark-sweep
      • 标记完成之后,将标记为1类的对象进行内存释放

  • img

  • Mark-compact

    • 垃圾回收完成之后,内存空间是不连续的。

    • 这样容易造成无法分配较大的内存空间的问题,从而触发垃圾回收。

    • 所以,会有Mark-compact步骤将未被回收的内存块整理为连续地内存空间。

    • 频繁触发垃圾回收会影响引擎的性能,内存空间不足时也会优先触发Mark-compact

img

垃圾回收优化

  • 增量标记
    • 如果用集中的一段时间进行垃圾回收,新生代倒还好,老生代如果遍历较大的对象,可能会造成卡顿。
    • 增量标记:使垃圾回收程序和应用逻辑程序交替运行,思想类似Time Slicing
  • 并行回收
    • 在垃圾回收的过程中,开启若干辅助线程,提高垃圾回收效率。
  • 并发回收
    • 在逻辑程序执行的过程中,开启若干辅助线程进行垃圾回收,清理和主线程没有任何逻辑关系的内存。

内存泄露场景

全局变量

// exm1
function Example(){
    exm = 'LeBron'   
}

// exm2
function Example(){
    this.exm = 'LeBron'
}
Example()

未清除的定时器

const timer = setInterval(() => {
    //...
}, 1000)

// clearInterval(timer)

闭包

function debounce(fn, time) {
  let timeout = null; 
  return function () {
    if (timeout) {
      clearTimeout(timeout);
    }

    timeout = setTimeout(() => {
      fn.apply(this, arguments);
    }, time);
  };
}

const fn = debounce(handler, 1000); // fn引用了timeout

未清除的DOM元素引用

const element = {
    // 此处引用了DOM元素
    button:document.getElementById('LeBron'),
    select:document.getElementById('select')
}

document.body.removeChild(document.getElementById('LeBron'))

如何检测内存泄漏

这个其实不难,浏览器原带的开发者工具Performance就可以

  • 步骤
    • F12打开开发者工具
    • 选择Performance工具栏
    • 勾选屏幕截图和Memory
    • 点击开始录制
    • 一段时间之后结束录制
  • 结果
    • 堆内存会周期性地分配和释放
    • 如果堆内存的min值在逐渐上升则存在内存泄漏

img

优化内存使用

1、尽量不在for循环中定义函数

// exm
const fn = (idx) => {
    return idx * 2;
}

function Example(){
    for(let i=0;i<1000;i++){
        //const fn = (idx) => {
        //    return idx * 2;
        // }
        const res = fn(i);
    }
}

2、尽量不在for循环中定义对象

function Example() {
  const obj = {};
  let res = "";
  for (let i = 0; i < 1000; i++) {
    // const obj = {
    //   a: i,
    //   b: i * 2,
    //   c: i * 3,
    // };
    obj.a = i;
    obj.b = i * 2;
    obj.c = i * 3;
    res += JSON.stringify(obj);
  }
  return res
}

3、清空数组

arr = [0, 1, 2]
arr.length = 0; // 清空了数组,数组类型不变
// arr = []  // 重新申请了一块空数组对象内存

【推荐学习:javascript高级教程

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

37

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

37

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

19

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

16

2026.01.13

PHP缓存策略教程大全
PHP缓存策略教程大全

本专题整合了PHP缓存相关教程,阅读专题下面的文章了解更多详细内容。

6

2026.01.13

jQuery 正则表达式相关教程
jQuery 正则表达式相关教程

本专题整合了jQuery正则表达式相关教程大全,阅读专题下面的文章了解更多详细内容。

3

2026.01.13

交互式图表和动态图表教程汇总
交互式图表和动态图表教程汇总

本专题整合了交互式图表和动态图表的相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.13

nginx配置文件详细教程
nginx配置文件详细教程

本专题整合了nginx配置文件相关教程详细汇总,阅读专题下面的文章了解更多详细内容。

9

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.2万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号