文档章节

js内存空间的那点事

那小么
 那小么
发布于 2017/03/02 14:53
字数 1431
阅读 69
收藏 1

由于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的寄存器, 由编译器自动分配释放, 读写快, 存储的都是固定值(也就是原始类型);

    堆: 属于二级缓存,由我们分配释放, 要是没有手动的释放,在调用结束后可能由OS回收,其生命周期由虚拟机的垃圾回收算法来决定。存储的是引用类型;

在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内存空间也就这点事了..

最后欢迎大神来访!

 

© 著作权归作者所有

那小么
粉丝 3
博文 10
码字总数 9804
作品 0
朝阳
前端工程师
私信 提问
加载中

评论(1)

布莱恩奥复托杰森张
布莱恩奥复托杰森张
标题很是鲜明,进来越来越蒙 , 表达不够大众化
你不知道的JavaScript系列

1、你不知道的JavaScript–Item1 严格模式 2、你不知道的JavaScript–Item2 浮点数精度 3、你不知道的JavaScript–Item3 隐式强制转换 4、你不知道的JavaScript–Item4 基本类型和基本包装类...

大灰狼的小绵羊哥哥
03/19
0
0
《你不知道的JavaScript》系列分享专栏

《你不知道的JavaScript》系列分享专栏 你不知道的JavaScript”系列就是要让不求甚解的JavaScript开发者迎难而上,深入语言内部,弄清楚JavaScript每一个零部件的用途 《你不知道的JavaScrip...

开元中国2015
2018/12/01
47
0
JavaScript深入浅出第3课:什么是垃圾回收算法?

摘要: JS是如何回收内存的? 《JavaScript深入浅出》系列: JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼? JavaScript深入浅出第2课:函数是一等公民是什么意思呢? JavaScript...

Fundebug
07/03
29
0
前端进阶(第一期)-调用堆栈笔记

1-1 理解 Javascript 执行上下文和执行栈 原文地址 知识点有: JavaScript程序的内部执行机制; 理解执行上下文和执行栈; 理解以上知识点有助于理解JavaScript的提升机制、作用域和闭包 执行...

xszi
2018/12/04
0
0
JavaScript-V8引擎

一、浏览器内核-渲染引擎 渲染就是根据描述或者定义构建一个数据模型,生成图形的过程。 浏览器内核就是将页面(Html、Css、JavaScript)构建成可视化、可听化的多媒体结果。 我们也可以将浏...

蜗牛的北极星之旅
09/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

带你了解 Java内存模型

Java内存模型的规定: 1、所有变量存储在主内存中; 2、每个线程都有自己的工作内存,且对变量的操作都是在工作内存中进行; 3、不同线程之间无法直接访问彼此工作内存中的变量,要想访问只能...

linux-tao
5分钟前
1
0
.net c# datetime转string 时间转字符串

.net c# datetime转string 时间转字符串 .net c# datetime转string 时间转字符串 刚开始接触net 时间转换字符串 一搜索出来的全是 字符串转时间,要么就是系统当前时间转字符串 就没有一个指...

青峰Jun19er
7分钟前
1
0
hbase demo

HbaseDao public class HbaseDao {@Testpublic void insertTest() throws Exception {Configuration conf = HBaseConfiguration.create();conf.set("hbase.zookeeper.qu......

Garphy
16分钟前
1
0
IT兄弟连 HTML5教程 HTML5表单 多样的输入类型2

4 range range类型用于包含一定范围内数字值的输入域,跟number一样,我们还可以对数值设置限定,range类型显示为滑动条用法如下: 上述代码使用了range类型输入框,为该类型设置了数值范围为...

老码农的一亩三分地
17分钟前
1
0
对比不同的数据库连接的异同

博主在学习和使用数据库连接时,遇到的问题, 这个几个数据库连接究竟有什么不同? 到底什么时候该使用哪个会更好一点? 带着这个问题我们先去了解常见的数据库连接 1. 常见的数据库连接有哪些?...

理性思考
19分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部