js内存空间的那点事
由于js具有自动垃圾回收机制,导致接触js后一直没去关注js的内存分配及变量回收等原理,只是懵懂的了解用变量标记法(null)可以手动的去清除或是回收;是时候弥补这个大坑了...
垃圾回收两种方法 一种是 标记清除法另外一种是计数清除法,下面都会提到;
先来回顾/了解下垃圾回收实现算法----Mark-and-sweep, 此算法实现步骤:
垃圾回收器创建了一个“roots”列表。Roots 通常是代码中全局变量的引用。JavaScript 中,“window” 对象是一个全局变量,被当作 root 。window 对象总是存在,因此垃圾回收器可以检查它和它的所有子对象是否存在(即不是垃圾);
所有的 roots 被检查和标记为激活(即不是垃圾)。所有的子对象也被递归地检查。从 root 开始的所有对象如果是可达的,它就不被当作垃圾。
所有未被标记的内存会被当做垃圾,收集器现在可以释放内存,归还给操作系统了。
可以简单的理解为 垃圾回收器会从window开始递归的标记window下所有子对象,在能访问到的子对象上边做个标记 告诉收集器这个对象/属性我罩着 你不能动.而那些没被标记的就视为"垃圾", 收集器会将它们释放掉, window只是roots之一 对于其他的对象来讲也是一样的 ;
JS变量类型分为两种即 原始类型(Number, String, Boolean, null, undefined)与引用类型(Object, Function, Array);
栈: 遵循着后进先出,先进后出的原则, 属于一级缓存, 地位相当于cpu的寄存器, 由编译器自动分配释放, 读写快, 存储的都是固定值(也就是原始类型);
堆: 属于二级缓存,由我们分配释放, 要是没有手动的释放,在调用结束后可能由GC回收,其生命周期由虚拟机的垃圾回收算法来决定。存储的是引用类型;
在Js中 是不许直接操作堆的, 所以栈与堆的区分不是那么严谨, 只要用到了堆, 必然也用到了栈;上一段代码帮助理解:
var a = 1,
b = {m:20};
看起来像这样:

可以清晰的看到在栈内存中变量b 存的是一个地址(引用地址,这个地址存放的就是{m: 20}), 由此我们可以看到js是不能直接操作堆的,操作的是这个引用地址; 而这个地址存放于栈中, 这就好理解为什么js栈与堆区分的不是那么严谨了.如果我们改变b的值,那会发生些什么,好,把b 改成b = [1, 2, 3]:

{m: 20}成了孤儿了.没人罩着他了,所以os会处理掉. 这里就是os的另一种回收条件了--计数清除.将一个引用类型的值赋值给一个变量,那么这个引用类型的值的引用次数就加1,相反,如果这个变量被赋值了其他值,这个引用类型的值的引用次数就减1,当引用次数为0时,就说明没有办法再访问这个引用类型的值了,那么她所占的内存空间会被垃圾回收器给回收;
接下来深浅复制就好理解了. 浅复制复制的引用地址, b复制了a的引用地址 他俩只要有一个对地址内容进行改变别人都会收到. 就像是你吧自家钥匙给了一朋友,他买了一个新电脑进来, 当你回家你也会发现这个电脑;深复制呢,没错你给你朋友的不在是一把钥匙而是一个房子, 这样他在那房子干点什么你完全不知道也不受影响.下面在看看执行环境与栈之间的关系,看一段代码:
var a = 1;
function fn(){
var b = 2;
function fn1(){
console.log(b);
}
fn1();
}
fn();
运行后大致如下:

先进后出,所以会先进入fn1的执行环境..当fn1执行完在进入fn..一直到全局的执行环境,全局执行上下文永远处于栈底.截止到这类似下面这些题一看就会了..
var a = 1,
b = a;
a = 2;
//b?
没错 b还是1; 因为1是number 位于栈内存, b=a 的时候会深复制过来;
var a = {n: 1},
b = a;
a.n = 2;
//b.n?
对于这种一年级的问题我们先放一放, 考虑这段代码会引发什么问题(不用考虑兼容性):
var obj = document.getElementById("button");// 假设可以获取到这个id为 button的Dom元素;
obj.addEventListener("click",function(){
obj.style.background = "#f00";
},false);
确实会引发内存泄漏的情况, 原因就是回调里边使用obj 保留了对外部obj的引用,导致不能被回收.;
类似这样的:
var num= 12;
setInterval(function() {
var obj = document.getElementById('button');
if(obj) {
obj.innerHTML = num;
}
}, 1000);
内存泄漏不是想避免就能避免的, 写代码有意识的防范固然很重要,也要学会使用调试工具进行探查.
对还有一点:
解除引用并不代表收回该值所占的内存,解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其收回;好吧. 对于js内存空间也就这点事了..
js内存空间的那点事的更多相关文章
- JS内存空间详细图解
JS内存空间详细图解 变量对象与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机 ...
- js内存空间详细图解-笔记
原文参考http://mp.weixin.qq.com/s/NGqdjhoU3MR9LD0yH6tKIw 栈-先进后出堆-类比成书于书架(形象),只要知道Key就可以找到value 基础数据类型(Un ...
- 前端高质量知识(一)-JS内存空间详细图解
变量对象与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机制,所 ...
- js内存空间
堆数据结构 堆数据结构是一种树状结构.它的存取数据的方式与书架和书非常相似.我们只需要知道书的名字就可以直接取出书了,并不需要把上面的书取出来.JSON格式的数据中,我们存储的key-value可以是 ...
- js内存空间及this关键词详解
http://mp.weixin.qq.com/s/FYFepXmkzzDYNLKhpovYFA
- js基础梳理-内存空间
我估计有很多像我这样非计算机专业的人进入到前端之后,总是在写业务代码,思考什么什么效果如何实现,导致很多基础概念型的东西都理解得并不太清楚.经常一碰到群里讨论的些笔试题什么的,总觉得自己像是一个假前端 ...
- js内存深入学习(一)
一. 内存空间储存 某些情况下,调用堆栈中函数调用的数量超出了调用堆栈的实际大小,浏览器会抛出一个错误终止运行.这个就涉及到内存问题了. 1. 数据结构类型 栈: 后进先出(LIFO)的数据结构 堆 ...
- 【进阶1-3期】JavaScript深入之内存空间详细图解(转)
这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://mp.weixin.qq.com/s/x4ZOYysb9XdT1grJbBMVkg 今天介绍的是JS内存空间,了解内存空间中的堆和 ...
- 由js深拷贝引起的对内存空间的一些思考
数据类型 js常用数据类型分为基本类型和引用类型 基本类型:null.undefined.数值型.字符串型.布尔型 引用类型:数组.对象 内存空间 var a = [1, 2, 3]; var b = ...
随机推荐
- python的相对导入
最近断断续续学习flask,学到蓝本时候有点小问题卡住了,问题如下 导入包的时候py文件里使用了相对路径导入,但是这种导入方法不是很明白,就自己搜索加实验了终于有点眉目了 先定义一个包 adb包 这个 ...
- 2018-2019-2 20175213实验三《敏捷开发与XP实践》实验报告
一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:吕正宏 学号:20175213 指导教师:娄嘉鹏 实验日期:2019年4月29日 实验时间:13:45 - 21:00 实验序号:实验 ...
- uboot 设备树 libfdt
http://www.cnblogs.com/leaven/p/6295999.html
- vi 操作
vi 3种模式:1命令行模式,2插入模式,3末行模式 Vim启动后直接进入的是命令行模式,命令行模式顾名思义就是可以输入各种命令的意思, 1. 命令行下按i键进入“插入模式”,命令行下按:键进入“末行 ...
- as3:sprite作为容器使用时,最好不要指定width,height
除 TextField 和 Video 对象以外,没有内容的显示对象(如一个空的 Sprite)的高度为 0,即使您尝试将 height 设置为其它值,也是这样. 如果您设置了 height 属性,则 ...
- python的if条件判断
python的条件判断书写格式: 基本格式 if 条件判断: #条件判断通过,则执行下面的语句 执行语句 执行语句 ... else: #条件判断不通过,则执行下面的语句 执行语句 执行语 ...
- idea编辑项目出现【Information:java: javacTask: 源发行版 7 需要目标发行版 1.7】
在编译项目时候出现问题: Information:java: javacTask: 源发行版 7 需要目标发行版 1.7 解决方案:按着图片操作,这几个地方设置的一样就可以了
- Python+Selenium学习--案例介绍
1. 前言 前面讲解了那么多selenium的基础知识,下面用一个简单案例来介绍,此案例主要实现,运行测试,自动生成html报告,并发生邮件. 2. 测试案例 2.1 目录结构介绍 conf:配置信息 ...
- geckodriver问题
selenium.common.exceptions.WebDriverException: Message: Service geckodriver unexpectedly exited. Sta ...
- Pandas 合并merge
pandas中的merge和concat类似,但主要是用于两组有key column的数据,统一索引的数据. 通常也被用在Database的处理当中. 1.依据一组key合并 >>> ...