前端的角度讲讲内存

在JS中具有自动垃圾回收机制,对于前端开发来说,内存空间并不是被常常提起的概念,容易被大家忽视。很多东西的原理与内存息息相关,如:闭包、深签拷贝、执行上下文等,要弄清楚这些,必须对内存空间有清晰的认知才行。

堆栈段

栈:栈会自动分配内存空间,会自动释放内存,存放基本类型,占据固定大小的空间。

堆:动态分配的内存,大小不定也不会自动释放内存,存放的是引用数据类型。

栈的存取方式,先进后出,后进先出。可以想象成一个盒子,并且只有一个出口和入库,如图a2在栈低,肯定是最先进入盒子的,然后再试a3、a4、a5。那么在盒子中a5在最上面,也是最先出来的,如果想要a2出来那么必须先拿出来a5,其次a4、a3,最后才是a2。内存中栈空间就是这么个存储原理。
在这里插入图片描述
堆空间可以比喻成书架,我们只需要知道书的名字,就可在书架上找到那本书。和栈空间相比,就不用拿能某一个球,必须把上面的球全部拿出来。堆空间中就从顺序来说,就显得不那么重要。
在这里插入图片描述

堆栈段中存放数据

在栈空间中保存的是基础数据类型,number、string、boolean、undefined、null、symbol。而在堆空间中保存的是引用数据类型,array、object。js不允许直接访问堆空间中的位置,所以不能直接去操作对象的堆内存空间。那么在操作对象时,实际上是在操作对象的引用,而不是实际的对象。引用就相当于一个地址(上个例子的“书名”)

        let a = 1;
        let b = 'str'
        let c = { name: '张三' }
        let d = [1, 2, 3, 4]

在这里插入图片描述
我们可以看到c、d保存的是一个引用(相当于地址),当我们去访问c、d的值,首先访问的是该对象或数据的内存地址,然后在从堆空间中取的我们想要数据。

这里有个小例子

		let a = 10;
        let b = a;
        b = 20;
        console.log(a);//10

        let c = { name: '张三', age: 20 }
        let d = c
        d.age = 30;
        console.log(c.age);//30

在数据发生复制行为时,系统会自动为新的变量分配一个新值。当a = b时虽然值相同,但是已经都是独立的个体了,互不影响。当d = c时,是把一个对象复制给它,其实复制的是一个引用地址。虽然名字不同,但是保存的都是同一个引用地址。修改其中一个,对应的数据也会修改。
在这里插入图片描述

内存空间管理

因为JS有自动垃圾回收机制,内存的分配与回收都完全实现了自动管理

JS的内存生命周期:

1、分配你所需要的内存

2、使用分配到的内存(读、写)

3、不需要时将其内存释放。

        // 在内存中分配空间
        let a = { name: '张三', age: 20 }
        // 修改
        a.age = 30;
        a.name = '李四';
        // 使用完后,释放内存
        a = null;

JS有自动垃圾回收机制,原理是,找出不在继续使用的值,然后释放占用的内存。垃圾收集器会每隔固定时间段就执行一次释放操作。

在JS中,最常用的是通过标记清除的算法来找到那些数据是不在使用的,a = null其实仅仅是做了一个释放引用的操作,让a原本对应的值失去引用,脱离执行环境,这个值会在下一次垃圾收集器执行操作时被找到并释放。而在适当的时候解除引用,是提升性能的一个方式。

如果一个值不再需要了,引用数却不为0,垃圾回收机制是无法释放这块内存,从而导致 内存泄漏
(如:不正确的使用闭包)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值