由于js具有自动垃圾回收机制,导致接触js后一直没去关注js的内存分配及变量回收等原理,只是懵懂的了解用变量标记法(null)可以手动的去清除或是回收;是时候弥补这个大坑了...

垃圾回收两种方法 一种是 标记清除法另外一种是计数清除法,下面都会提到;

先来回顾/了解下垃圾回收实现算法----Mark-and-sweep, 此算法实现步骤

  1. 垃圾回收器创建了一个“roots”列表。Roots 通常是代码中全局变量的引用。JavaScript 中,“window” 对象是一个全局变量,被当作 root 。window 对象总是存在,因此垃圾回收器可以检查它和它的所有子对象是否存在(即不是垃圾);

  2. 所有的 roots 被检查和标记为激活(即不是垃圾)。所有的子对象也被递归地检查。从 root 开始的所有对象如果是可达的,它就不被当作垃圾。

  3. 所有未被标记的内存会被当做垃圾,收集器现在可以释放内存,归还给操作系统了。

可以简单的理解为 垃圾回收器会从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内存空间的那点事的更多相关文章

  1. JS内存空间详细图解

    JS内存空间详细图解 变量对象与堆内存 var a = 20; var b = 'abc'; var c = true; var d = { m: 20 } 因为JavaScript具有自动垃圾回收机 ...

  2. js内存空间详细图解-笔记

    原文参考http://mp.weixin.qq.com/s/NGqdjhoU3MR9LD0yH6tKIw 栈-先进后出堆-类比成书于书架(形象),只要知道Key就可以找到value 基础数据类型(Un ...

  3. 前端高质量知识(一)-JS内存空间详细图解

    变量对象与堆内存   var a = 20;   var b = 'abc';   var c = true;   var d = { m: 20 } 因为JavaScript具有自动垃圾回收机制,所 ...

  4. js内存空间

    堆数据结构 堆数据结构是一种树状结构.它的存取数据的方式与书架和书非常相似.我们只需要知道书的名字就可以直接取出书了,并不需要把上面的书取出来.JSON格式的数据中,我们存储的key-value可以是 ...

  5. js内存空间及this关键词详解

    http://mp.weixin.qq.com/s/FYFepXmkzzDYNLKhpovYFA

  6. js基础梳理-内存空间

    我估计有很多像我这样非计算机专业的人进入到前端之后,总是在写业务代码,思考什么什么效果如何实现,导致很多基础概念型的东西都理解得并不太清楚.经常一碰到群里讨论的些笔试题什么的,总觉得自己像是一个假前端 ...

  7. js内存深入学习(一)

    一. 内存空间储存 某些情况下,调用堆栈中函数调用的数量超出了调用堆栈的实际大小,浏览器会抛出一个错误终止运行.这个就涉及到内存问题了. 1. 数据结构类型 栈: 后进先出(LIFO)的数据结构  堆 ...

  8. 【进阶1-3期】JavaScript深入之内存空间详细图解(转)

    这是我在公众号(高级前端进阶)看到的文章,现在做笔记 https://mp.weixin.qq.com/s/x4ZOYysb9XdT1grJbBMVkg 今天介绍的是JS内存空间,了解内存空间中的堆和 ...

  9. 由js深拷贝引起的对内存空间的一些思考

    数据类型 js常用数据类型分为基本类型和引用类型 基本类型:null.undefined.数值型.字符串型.布尔型 引用类型:数组.对象 内存空间 var a = [1, 2, 3]; var b = ...

随机推荐

  1. C# String 与 StringBuilder

    String 字符串不可变性,每次为字符串进行增删或重写赋值会销毁原来的字符串,重新开辟内存空间,因此是非常消耗资源的 字符串可以看做是 char 数组,因此可以用 foreach 对其进行遍历,或者 ...

  2. Ubuntu安装pyucharm的专业版本

    看到了不错的教程,亲测有效. https://www.cnblogs.com/huozf/p/9304396.html

  3. python3之Django基础篇

    一.Django基础 Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站! Django的特点: 强大的数据库功能:拥有强大的数据库操作接口(QueryS ...

  4. OpenStack 安装:keystone服务

    在前面的章节里面,我们配置了基本环境,也安装keystone服务,并且创建了keystone的数据库,在这一篇里面,我们说怎么配置keystone. 首先编辑keystone服务,需要修改如下数据 编 ...

  5. 图像处理项目——生成csv文件提高读取效率

    利用pyhton脚本生成csv文件 *开发环境为windows PyCharm*使用的是pyhton脚本*生成人脸和人脸对应的标签的csv文件 一:主要步骤 1.载入对应路径2.提取每一张图片对应的位 ...

  6. Pains and Sickness 学习笔记

    Headaches can be very painful and can last for a long time. If you have a headache, your head hurts. ...

  7. 创建第一次C语言程序

    在这里我以VS2015为例,做演示.为什么要去演示怎样创建项目尼,因为我写第一个程序时,不知道该怎样用VS创建我的第一个应用程序. 第一步:打开VS环境如下 第二步:在开始出点击“新建项目”或在右上角 ...

  8. java 线程Thread 技术--volatile关键字

    java 语言中允许线程访问共享变量,为了保证共享变量能被准确和一致的更新,Java 语言提供了volatile 关键字,也就是我们所说的内存一致性: 问题抛出:(尝试去运行下面代码,以及将volat ...

  9. 设置textfield 文字左边距

    默认情况下,当向textField输入文字时,文字会紧贴在textField左边框上.我们可以通过设置textField的leftView,设置一个只有宽度的leftView.这样还不够,因为默认le ...

  10. HDU 3666.THE MATRIX PROBLEM 差分约束系统

    THE MATRIX PROBLEM Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...