前端小知识点(5):JS垃圾回收机制

目录

一、什么是垃圾回收

二.垃圾回收机制原理

三、垃圾回收方法

3.1 引用计数

3.2 标记清除

内存常见内存泄露以及解决方法

4.1 全局变量:

4.2 定时器和回调函数 

4.3 闭包 

4.4 没有清理DOM元素引用: 


一、什么是垃圾回收

垃圾回收是一种自动的内存管理机制。当计算机上的动态内存不再需要时,就应该予以释放,以让出内存。直白点讲,就是程序是运行在内存里的,当声明一个变量、定义一个函数时都会占用内存。内存的容量是有限的,如果变量、函数等只有产生没有消亡的过程,那迟早内存有被完全占用的时候。这个时候,不仅自己的程序无法正常运行,连其他程序也会受到影响。好比生物只有出生没有死亡,地球总有被撑爆的一天。所以,在计算机中,我们需要垃圾回收。需要注意的是,定义中的“自动”的意思是语言可以帮助我们回收内存垃圾,但并不代表我们不用关心内存管理,如果操作不当,JavaScript 中依旧会出现内存溢出的情况。

二.垃圾回收机制原理

垃圾回收基于两个原理:

1、考虑某个变量或对象在未来的程序运行中将不会被访问

2、向这些对象要求归还内存

而这两个原理中,最主要的也是最艰难的部分就是找到“所分配的内存确实已经不再需要了”。

三、垃圾回收方法

现在各大浏览器通常用采用的垃圾回收有两种方法:标记清除、引用计数。

3.1 引用计数

这是最初级的垃圾回收算法(老牌浏览器使用:IE)。引用计数的策略是跟踪记录每个值被使用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,这个值得引用次数就加一,如果该变量的值变成了另一个,则这个值得引用次数就减一,当这个值的引用次数为0的时候,说明没有变量在使用,这个值无法访问。由此可以将其占用的空间回收,这些垃圾回收器就会在运行时清理掉引用次数为0的值占用的空间,但这种方法容易引起内存泄漏,因为这种方式没有解决循环引用的问题,所以不建议使用!

function fun4(){
var obj = {}//引用类型变量,c的引用计数为0
var o = obj; //obj被o引用,obj的引用计数为1
var m = obj; //obj被m引用,obj的引用计数为2
o = {}  //o不再引用obj,obj的引用计数减为1
m = null //m不再引用obj,obj的引用计数减为0
}

但是引用计数存在一些问题:循环引用

function fun5(){var f = {};var g = {};f.userName = g;g.userName = f;//由于f和g互相引用,计数永远不可能为0}

3.2 标记清除

这是javascript中最常用的垃圾回收方式。当变量进入执行环境是,就标记这个变量为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。当变量离开环境时,则将其标记为“离开环境”。

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后。垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。

function fun3(){
var a = 1;
var b = 2;
//函数执行时,ab分别被标记,进入环境
}
fun3()  函数执行结束,ab被标记 离开环境 ,被回收

但是也要注意

function fun1(){var obj = {}
}
function fun2(){var obj = {}return obj;
}
var a = fun1();
var b = fun2();
fun1 执行时为 obj 分配了一块内存,但是随着函数执行结束,obj占用的空间也就被释放了
fun2 执行时,也为 obj 分配了内存,但是由于 obj最终被返回赋值给了 b 导致其依然被使用,所以 fun2 中的 obj 占用的内存不会被释放
  • 内存常见内存泄露以及解决方法

  • 4.1 全局变量:

function foo() {this.bar2 = '默认绑定this指向全局' // 全局变量=> window.bar2bar = '全局变量'; // 没有声明变量 实际上是全局变量=>window.bar
}
foo();解决方法:在函数内使用严格模式==》严格模式禁止this关键字指向全局对象function foo() {"use strict"; this.bar2 = "严格模式下this指向undefined"; bar = "报错";
}
foo();

4.2 定时器和回调函数 

当不需要setInterval或者setTimeout时,定时器没有被clear,定时器的回调
函数以及内部依赖的变量都不能被回收,造成内存泄漏。var someResource = getData();
setInterval(function() {var node = document.getElementById('Node');if(node) {node.innerHTML = JSON.stringify(someResource));// 定时器也没有清除}// node、someResource 存储了大量数据 无法回收
}, 1000);解决方法: 在定时器完成工作的时候,手动清除定时器。

4.3 闭包 

闭包可以维持函数内局部变量,使其得不到释放,造成内存泄漏。
function bindEvent() {var obj = document.createElement("XXX");var unused = function () {console.log(obj,'闭包内引用obj obj不会被释放');};// obj = null;
}
解决方法:手动解除引用,obj = null。

4.4 没有清理DOM元素引用: 


var refA = document.getElementById('refA');
document.body.removeChild(refA); // dom删除了
console.log(refA, "refA");  // 但是还存在引用 能console出整个div 没有被回收解决办法:refA = null;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux python pymysql,Python之pymysql的使用

在Python3.x中,可以使用pymysql来MySQL数据库的连接,并实现数据库的各种操作,本次博客主要介绍了pymysql的安装和使用方法。PyMySQL的安装一、.windows上的安装方法:在python3.6中,自带pip3,所以在python3中…

树莓派静态IP配置方法

一、网络接口文件 配置静态IP有个好处在于每次的访问IP是固定的,比如用到的samba服务器共享文件时可以不改动网络地址。树莓派网络接口在/etc/network/interfaces 文件中进行配置,打开该文件:sudo vi /etc/network/interfaces 可以看到第四行…

带可变参数的宏函数和普通函数实现

From: http://www.vimer.cn/2010/03/cc%E5%AE%8F%E5%AE%9A%E4%B9%89%E7%9A%84%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0.html 编写代码的过程中,经常会输出一些调试信息到屏幕上,一般会调用printf这类的函数。 但是当调试解决之后,我们需要手工将…

SAP 免费赠与客户货物的销项税处理

免费赠与客户货物的销项税处理 如果免费赠与客户货物却要体现销项税,如何处理?在实际业务中因为免费货物是不免税的。所以大家总是以为使用0费用解决但是有一种情况是存在于视同销售。 即D:销售费用 C:销项税 SAP中的处理逻…

前端小知识点(2):普通字符串和new String有什么区别

目录 一、其实不仅字符串 二、那么到底为什么? 三、代码案例 四、运行结果 一、其实不仅字符串 var str abc; typeof str > string //他不是对象,可以有方法或者属性 var num 123; //他不是对象,可以有方法或者属性 typeof num …

linux更新命令yum,Linux中升级更新命令yum upgrade和yum update的区别

Linux中升级更新命令yum upgrade和yum update的区别更新时间:2019-10-31 17:21最满意答案Linux升级命令有两个分别是yum upgrade和yum update, 这个两个命令是有区别的:复制代码代码如下:yum -y update升级所有包同时也升级软件和系统内核复制代码代码如下:yum -y u…

Linux 管理登陆的用户/查看/剔除

Linux是多用户操作系统,支持多用户同时在线,支持对登陆用户的管理:查看与剔除等。 一、查看在线用户命令 命令: w 二、查看登录记录命令 命令 last 三、剔除在线用户命令 命令:sudo pkill -kill -t usr 四、pkill…

Windows下 maven3.0.4的安装步骤+maven配置本地仓库

简单讲下maven的安装步骤: 1.在安装maven之前,先确保已经安装JDK1.6及以上版本,并且配置好环境变量。 2.下载maven3,最新版本是Maven3.0.4 ,下载地址:http://maven.apache.org/download.html 下载apache…

C语言日志操作类实例

包含三个主要的文件&#xff1a;joefunction.h(c), m.c(主函数文件) 1. m.c #include <stdio.h> #include <string.h> #include <time.h> #include "joefunction.h"extern FILE *g_logFile;int main(int argc, char *argv[]) {char temp[16] {0}…

ESX与ESXi管理员必备25个命令

ESX与ESXi管理员必备25个命令VMware ESX和ESXi命令这些VMware ESX和ESXi的命令可以运行在ESX服务控制台&#xff08;本地或远程使用Secure Shell&#xff09;或RCLI&#xff08;在VMware Infrastructure 3&#xff09;和vSphere CLI的&#xff08;在vSphere&#xff09;。在RCL…

前端小知识点(3):JavaScript 单线程

目录 一、为什么 JavaScript 是单线程&#xff1f; 二、JavaScript是单线程&#xff0c;怎样执行异步的代码&#xff1f; 三、事件循环机制 四、代码1 五、结果1 六、代码2 七、结果2 一、为什么 JavaScript 是单线程&#xff1f; JavaScript 语言的一大特点就是单线程…

Linux安装samba的过程,Samba安装全过程

对于linux与windows共享&#xff0c;和平共处&#xff0c;我们可以用Samba软件Samba是一套免费的开源软件&#xff0c;可以在linux或其他类unix操作系统上实现windows域控制器&#xff0c;文件服务&#xff0c;打印服务等。Samba实现了windows系统所使用的核心网络协议&#xf…

树莓派UART串口编程--使用wiringPi库-C开发【2-修改驱动】

一、前言 上一篇博文记录了使用wiringPi提供的串口驱动wiringSerial.c wiringSerial.h&#xff0c;并基于该驱动对串口进行简单的通信&#xff0c;测试中发现该串口的驱动比较简单&#xff0c;接收数据会存在分包的现象&#xff0c;另外一点是串口配置只提供了波特率参数配置&…

《软件开发计划》

校友聊项目开发计划书 项目名称&#xff1a;校友聊 1.引言 1.1编写目的 编写本文档的目的是为了校园内网的用户使用本软件进行文字&#xff0c;视频聊天&#xff0c;而不耗费内网的外网的流量。 1.2背景 基于校园内网用户对流量的强大需求&#xff0c;以及考虑到其中一些特殊用…

【转】全面理解javascript的arguments,callee,caller,call,apply概念(修改版)

(注&#xff1a;在看到大家如此关注JS里头的这几个对象&#xff0c;我试着把原文再修改一下&#xff0c;力求能再详细的阐明个中意义 2007-05-21&#xff09;在提到上述的概念之前&#xff0c;首先想说说javascript中函数的隐含参数&#xff1a;arguments Arguments 该对象代表…

windows延缓写入失败相关问题解决办法

From: http://www.ggsafe.com/news/1324547234222.shtml 我们在使用电脑时&#xff0c;有时在不正常关机后电脑会出现这样那样的问题。windows延缓写入失败就是其中一个&#xff0c;很多网友在互联网上发帖求助windows延缓写入失败怎么办&#xff0c;出现这种情况一般都是由于电…

wince linux 性能,wince remote call profiler(性能分析)

如何使用1 建立工程,CPU类型必须于目标机型一致如ARMV4I,所以选择WCE Application,然后选择empty project2 project settings 中,link页,Object/library modules中添加 cecap.lib(前面有空格),Ingore libraries中添加,libc.lib(前面有逗号).C/C页Project Options最后添加 /call…

前端小知识点(4):JS 运行机制和存储

目录 被忽视的内存管理 JS工作原理 JS代码如何运行 JavaScript内存的生命周期 栈内存、堆内存 代码案例 运行结果 被忽视的内存管理 JavaScript不像C、C等语言——程序员必须通过调用内存管理接口&#xff0c;比如 malloc()和free()&#xff0c;自己手动分配和释放内存。…

201506230818_《JavaScript权威指南(第六版)——callee和caller、对象属性用作实参、自定义函数属性》(P175-180)...

1. callee 正在执行的函数。使用方法&#xff1a;arguments.callee... caller 正在调用执行函数的函数。 2.对象属性用作实参&#xff0c;形如&#xff1a;function fn(arg) { var arg.name name || Josn, arg.age age || 60 , ... } 3. 在传入实参时候&#xff0c;宁愿在检查…

VIM选择文本块

From: http://hi.baidu.com/mykledge/blog/item/d42e4d63f57232d48cb10d6c.html 在正常模式下&#xff08;按ESC进入&#xff09;按键v进入可视化模式&#xff0c;然后按键盘左右键或h,l键即可实现文本的选择。 其它相关命令&#xff1a; v&#xff1a;按字符选择。经常使用的模…