js内存使用

198 阅读4分钟

引言

前端同学最常接触的逻辑程序语言想必就是js,那么大家是否都清楚, 咱们平日里所写的js代码,是如何使用内存资源的呢? 有兴趣的小伙伴可以接着看;

js内存分配

日常内存使用

首先让我们先回顾下我们日常是怎么使用内存的:

    // 变量的定义方法
    var a = 'test1'

    let b = 222

    const c = '333'

    d = true

    function e() {
        //...
    }

    let f = {test:'fff'}
    

咱们平时就是以这些方式定义变量,对于我们来说,是定义了一个用于存储数据的变量, 那么对于内存资源来说,发生了什么呢?

栈(stack)内存 与 堆(heap)内存

在js中,会将变量分为两类,并分别存储到栈(stack)与堆(heap)中; 那么什么是栈,什么是堆,它们有什么区别?

栈(stack)内存

栈内存用于存储已知固定大小的变量值,并且每个变量分配的内存区域都差不多大小;
主要包括:String、Boolean、Number、Undefined、Null、以及对象引用的指针;
栈内存具有以下特点:
1、每个单元分配内存小,并且大小相似;
2、存储的都是大小已知的基础变量(null虽然是object,但是因为大小固定,也存储在栈);
3、栈内存空间远远小于堆内存;

堆(heap)内存

堆内存用于存储大小不固定的变量值,堆中存储的值有可能在未来不断增大;
主要包括:引用类型(Object、Array);
堆内存具有以下特点:
1、系统分配的内存空间大;
2、存储的数据类型为大小未知的数据;
3、堆内存空间远大于栈内存;

静态内存分配 与 动态内存分配

静态内存分配

静态内存分配是针对存储静态数据的过程。
(静态数据是指引擎在编译时知道大小的数据);
其实,就是对于栈内存的分配过程;

动态内存分配

动态内存分配是针对存储动态数据的过程。
(动态数据是指引擎在编译时知道大小未知数据,在之后可能增大或减小);
其实,就是对于堆内存的分配过程;

无标题.png

暂停思考区

所以,在我们js代码中,我们每定义(显示or隐式)一个变量,都将在栈或堆内存中开辟一块内存空间; 根据我们上述常用定义方式,开辟不同的存储方式; 那么我们知道了内存存储特点,那么我们平时写代码,应该怎样正确使用js控制内存呢?

js内存使用

这里列几条日常使用js控制内存需要注意的地方:
1、避免过多全局变量使用;
2、慎用闭包;
3、慎用未知第三方库;
4、控制动态对象的大小,防止无限增加;
5、及时清除未使用变量;
如果我们不注意内存的使用,有很大的可能造成内存的泄漏;

js内存释放

谈到内存释放,就得依靠js的垃圾回收机制了,简称GC;
关于GC的文章,各个博客已经特别多了,这里按自己的理解,总结一下GC;

现阶段js的垃圾回收,主要依赖-可达性-这个概念;
如果一个值可以通过引用或引用链,从某个值(这个值被称为根)访问到,则认为这个值是可达的;
只要这个值,可达,那么就一定在内存中存储着;

js内存释放具有自动性,当函数或程序运行结束,将进行垃圾回收;
那些没有被引用的变量,就将会被GC回收释放;
当然,我们也可以提前手动释放:将值设为null或者undefined

注意,当我们将变量设为null或者undefined时,并没有马上释放内存,
而会等到下一轮GC工作,发现变量已经没有被引用,就会将其回收;

js内存泄漏

内存泄漏的本质,就是应该被回收的内存资源,发生异常,没有被正确回收;
js中引起内存泄漏的情况有以下几种:
1、闭包
2、全局变量使用过多,并忘记释放
3、dom节点的引用,并未清除完全
4、定时器使用,并忘记释放
这里就不再做多余的缀诉,注意这几种情况,并及时释放内存即可;

小结

文章主要从js内存分配、内存使用、内存释放、内存泄漏几点,简单的阐述了,
如果想要深入了解相关知识,还是需要再去细致的阅读一下相关文章,
这里就仅仅是抛转引玉了;