垃圾回收与内存泄漏

前端面试大全·JavaScript垃圾回收与内存泄漏

🌟经典真题

🌟什么是内存泄露

🌟JavaScript 中的垃圾回收

🌟标记清除

🌟引用计数

🌟真题解答

🌟总结


🌟经典真题

  • 请介绍一下 JavaScript 中的垃圾回收站机制

🌟什么是内存泄露

程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。

对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。

也就是说,不再用到的内存,如果没有及时释放,就叫做内存泄漏(memory leak)。

🌟JavaScript 中的垃圾回收

浏览器的 Javascript 具有自动垃圾回收机制(GCGarbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。其原理是:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存

但是这个过程不是实时的,因为其开销比较大并且 GC 时停止响应其他操作,所以垃圾回收器会按照固定的时间间隔周期性的执行。

不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直至函数结束,而闭包中由于内部函数的原因,外部函数并不能算是结束。

下面是一段示例代码:

function fn1() {
    var obj = {name: 'zhangsan', age: 10};
}
function fn2() {
    var obj = {name:'zhangsan', age: 10};
    return obj;
}

var a = fn1();
var b = fn2();

在上面的代码中,我们首先声明了两个函数,分别叫做 fn1 和 fn2

当 fn1 被调用时,进入 fn1 的环境,会开辟一块内存存放对象 {name: 'zhangsan', age: 10}。而当调用结束后,出了 fn1 的环境,那么该块内存会被 JavaScript 引擎中的垃圾回收器自动释放;

在 fn2 被调用的过程中,返回的对象被全局变量 b 所指向,所以该块内存并不会被释放。

这里问题就出现了:到底哪个变量是没有用的?

所以垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标记,以备将来收回其内存。

用于标记的无用变量的策略可能因实现而有所区别,通常情况下有两种实现方式:标记清除引用计数

引用计数不太常用,标记清除较为常用。

🌟标记清除

JavaScript 中最常用的垃圾回收方式就是标记清除。

当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。

从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。

而当变量离开环境时,则将其标记为“离开环境”。

function test(){
  var a = 10 ; // 被标记 ,进入环境 
  var b = 20 ; // 被标记 ,进入环境
}
test(); // 执行完毕 之后 a、b 又被标离开环境,被回收。

垃圾回收器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方式)。

然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记(闭包)。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。

最后,垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

到目前为止,IE9+、Firefox、Opera、Chrome、Safari 的 JS 实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

🌟引用计数

引用计数的含义是跟踪记录每个值被引用的次数。

当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是 1。如果同一个值又被赋给另一个变量,则该值的引用次数加 1

相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数减 1。当这个值的引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。

这样,当垃圾回收器下次再运行时,它就会释放那些引用次数为 0 的值所占用的内存。

function test() {
    var a = {};	// a 指向对象的引用次数为 1
    var b = a;	// a 指向对象的引用次数加 1,为 2
    var c = a;	// a 指向对象的引用次数再加 1,为 3
    var b = {};	// a 指向对象的引用次数减 1,为 2
}

Netscape Navigator3 是最早使用引用计数策略的浏览器,但很快它就遇到一个严重的问题:循环引用

循环引用指的是对象 A 中包含一个指向对象B的指针,而对象 B 中也包含一个指向对象 A 的引用。

function fn() {
    var a = {};
    var b = {};
    a.pro = b;
    b.pro = a;
}
fn();

以上代码 a 和 b 的引用次数都是 2fn 执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为 a 和 b 的引用次数不为 0,所以不会被垃圾回收器回收内存,如果 fn 函数被大量调用,就会造成内存泄露。在 IE7 与 IE8 上,内存直线上升。

🌟真题解答

  • 请介绍一下 JavaScript 中的垃圾回收站机制

参考答案:

JavaScript 具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。

JavaScript 常见的垃圾回收方式:标记清除引用计数方式。

1、标记清除方式:

  • 工作原理:当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

  • 工作流程:

  • 垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记;

  • 去掉环境中的变量以及被环境中的变量引用的变量的标记;

  • 被加上标记的会被视为准备删除的变量;

  • 垃圾回收器完成内存清理工作,销毁那些带标记的值并回收他们所占用的内存空间。

2、引用计数方式:

  • 工作原理:跟踪记录每个值被引用的次数。

  • 工作流程:

  • 声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是 1

  • 同一个值又被赋值给另一个变量,这个引用类型值的引用次数加 1

  • 当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减 1

  • 当引用次数变成 0 时,说明没办法访问这个值了;

  • 当垃圾收集器下一次运行时,它就会释放引用次数是 0 的值所占的内存。

🌟总结

本篇文章是关于JavaScript的一道面试题,后续还会持续更新HTML、CSS、JavaScript、Node.js、Vue.js、网络等前端相关面试题。如果文中出现有瑕疵的地方各位通过评论或者私信联系我,我们一起进步,有兴趣的伙伴可以关注订阅: 前端面试题大全  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/209342.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

混合使用Windows和Linux子系统的工具和命令

文章目录 在Windows中运行Linux命令使用PowerShell混合使用Linux和Windows命令通过power shell在Windows混合使用Linux工具在Linux中混合使用Windows 工具 推荐阅读 Windows和Linux的工具和命令可以通过WSL互换使用。 可以在Linux子系统中运行Windows命令,也可以在W…

redis主从复制模式和哨兵机制

目录 第一章、主从复制模式1.1)Redis 主从复制模式介绍1.2)Redis 主从复制实现、 第二章、哨兵机制2.1)容灾处理之哨兵2.2)Sentinel 配置 第一章、主从复制模式 1.1)Redis 主从复制模式介绍 ①单点故障:数…

【C++】string类模拟实现过程中值得注意的点

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.有关const的使用 &#x…

常用sql记录

备份一张表 PostgreSQL CREATE TABLE new_table AS SELECT * FROM old_table;-- 下面这个比上面好,这个复制表结构时,会把默认值、约束、注释都复制 CREATE TABLE new_table (LIKE old_table INCLUDING ALL) WITHOUT OIDS; INSERT INTO new_table SELE…

一进三出宿舍限电模块的改造升级

一进三出宿舍限电模块改造升级石家庄光大远通电气有限公司智能模块功能特点: 电能控制功能:可实施剩余电量管理,电量用完时将自动断电; 剩余电量可视报警提示功能:剩余电量可视,并当电量剩余5度时&#xff…

图解java.util.concurrent并发包源码系列——深入理解定时任务线程池ScheduledThreadPoolExecutor

深入理解定时任务线程池ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor作用与用法ScheduledThreadPoolExecutor内部执行流程DelayedWorkQueueScheduledFutureTask源码分析任务提交ScheduledFutureTask的属性和方法delayedExecute(t) 任务执行ScheduledFutureTask.su…

Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊

文章目录 Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊使用 RenderEffect 模糊使用 Vukan 模糊使用 GLSL 模糊RS、Vukan、RenderEffect、GLSL 效率对比 Android Bitmap 使用Vukan、RenderEffect、GLSL实现模糊 本文首发地址 https://blog.csdn.net/CSqingchen/articl…

行内元素和块级元素分别有哪些?有何区别?怎样转换?

行内元素和块级元素分别有哪些? 常见的块级元素: p、div、form、ul、li、ol、table、h1、h2、h3、h4、h5、h6、dl、dt、dd 常见的行级元素: span、a、img、button、input、select 有何区别? 块级元素: 总是在新行上…

Centos7安装

想学Vmware安装可以看下下面链接,不想就算了 https://blog.csdn.net/weixin_43895362/article/details/134723073 选择第一项,安装直接CentOS 7,回车 稍等后出现进入下图,选择中文,这个只是安装时的语言 首先设置时间,时区选择上海,查看时…

JVM 类的加载

面试题: 简述 Java 类加载机制?(百度) JVM类加载机制 (滴滴) JVM中类加载机制,类加载过程,什么是双亲委派模型? (腾讯) JVM的类加…

【UE】射线检测与物品高亮显示

效果 步骤 1. 新建一个空白模板工程 2. 添加一个第一人称游戏内容包 3. 打开项目设置,创建一个新的通道检测 取消勾选“自动曝光” 4. 打开第一人称角色蓝图“BP_FirstPersonCharacter”,添加一个新图表,命名为“射线检测” 添加如下节点&a…

LeNet对MNIST 数据集中的图像进行分类--keras实现

我们将训练一个卷积神经网络来对 MNIST 数据库中的图像进行分类,可以与前面所提到的CNN实现对比CNN对 MNIST 数据库中的图像进行分类-CSDN博客 加载 MNIST 数据库 MNIST 是机器学习领域最著名的数据集之一。 它有 70,000 张手写数字图像 - 下载非常简单 - 图像尺…

CMMI认证含金量高吗

一、CMMI认证含金量解答 CMMI,即能力成熟度模型集成,是由美国卡内基梅隆大学软件工程研究所开发的一种评估企业软件开发过程成熟度的模型。CMMI认证的含金量究竟高不高呢?答案是肯定的。CMMI认证被誉为软件开发行业的“金牌标准”&#xff0…

vue循环v-for遍历图表

循环遍历图表 index.vue主页面 <view v-if"powerPage"><view v-for"(item, index) in powerDetailsData.addMap" :key"index"><PowerEChartsCity:echartData"powerDetailsData.addMap[index]"></PowerEChartsC…

经典神经网络——VGGNet模型论文详解及代码复现

论文地址&#xff1a;1409.1556.pdf。 (arxiv.org)&#xff1b;1409.1556.pdf (arxiv.org) 项目地址&#xff1a;Kaggle Code 一、背景 ImageNet Large Scale Visual Recognition Challenge 是李飞飞等人于2010年创办的图像识别挑战赛&#xff0c;自2010起连续举办8年&#xf…

Unity 关于SpriteRenderer 和正交相机缩放

float oldWidth 750f;float oldHeight 1334f;float newWidth Screen.width;float newHeight Screen.height;float oldAspect oldWidth / oldHeight;float newAspect newWidth / newHeight;//水平方向缩放float horizontalCompressionRatio newAspect / oldAspect;//垂直…

Python 中的 FileSystem Connector:打通文件系统的便捷通道

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python 中的 FileSystem Connector&#xff1a;打通文件系统的便捷通道&#xff0c;全文4100字&#xff0c;阅读大约11分钟。 在现代软件开发中&#xff0c;文件系统是不可或…

【Python表白系列】一起去看流星雨吧!(完整代码)

文章目录 流星雨环境需求完整代码详细分析系列文章流星雨 环境需求 python3.11.4PyCharm Community Edition 2023.2.5pyinstaller6.2.0(可选,这个库用于打包,使程序没有python环境也可以运行,如果想发给好朋友的话需要这个库哦~)【注】 python环境搭建请见:https://want5…

数据结构算法-选择排序算法

引言 说起排序算法&#xff0c;那可就多了去&#xff0c;首先了解什么叫排序 以B站为例&#xff1a; 蔡徐坤在B站很受欢迎呀&#xff0c;先来看一下综合排序 就是播放量和弹幕量&#xff0c;收藏量 一键三连 都很高这是通过一些排序算法 才能体现出综合排序 蔡徐坤鬼畜 按照播…

flutter-一个可以输入的数字增减器

效果 参考文章 代码 在参考文章上边&#xff0c;主要是改了一下样式&#xff0c;逻辑也比较清楚&#xff0c;对左右两边添加增减方法。 我在此基础上加了_numcontroller 输入框的监听。 加了数字输入框的控制 keyboardType: TextInputType.number, //设置键盘为数字 inputF…