本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了垃圾回收的相关问题,垃圾回收是JavaScript的隐藏机制,下面一起来看一下,希望对大家有帮助。
【相关推荐:javascript视频教程、web前端】
一、前言
垃圾回收是JavaScript
的隐藏机制,我们通常无需为垃圾回收劳心费力,只需要专注功能的开发就好了。但是这并不意味着我们在编写JavaScript
的时候就可以高枕无忧了,伴随着我们实现的功能越来越复杂,代码量越积越大,性能问题就变的越来越突出。如何写出执行速度更快,而且占用内存更小的代码是程序员永无止歇的追求。一个优秀的程序员总是能在极其有限的资源下,实现惊人的效果,这也正式芸芸众生和高高在上的神祗之间的区别。
二、何为垃圾
代码执行在计算机的内存中,我们在代码中定义的所有变量、对象、函数都会在内存中占用一定的内存空间。在计算机中,内存空间是非常紧张的资源,我们必须时时刻刻注意内存的占用量,毕竟内存条非常贵!如果一个变量、函数或者对象在创建之后不再被后继的代码执行所需要,那么它就可以被称作垃圾。
虽然从直观上理解垃圾的定义非常容易,但是对于一个计算机程序来说,我们很难在某一时刻断定当前存在的变量、函数或者对象在未来不再使用。为了降低计算机内存的开销,同时又保证计算机程序正常执行,我们通常规定满足以下任一条件的对象或者变量为垃圾:
- 没有被引用的对象或者变量;
- 无法访问到的对象(多个对象之间循环引用);
没有被引用的变量或者对象相当于一座没有门的房子,我们永远都无法进入其中,因此不可能在用到它们。无法访问到的对象之间虽然具备连通性,但是仍然无法从外部进入其中,因此也无法再次被利用。满足以上条件的对象或者变量,在程序未来执行过程中绝对不会再次被采用,因此可以放心的当作垃圾回收。
当我们通过以上定义明确了需要丢弃的对象,是否就意味着剩余的变量、对象中就没有垃圾了呢?
不是的!我们当前分辨出的垃圾只是所有垃圾的一部分,仍然会有其他垃圾不满足以上条件,但是也不会再次被使用了。
这是否可以说满足以上定义的垃圾是“绝对垃圾”,其他隐藏在程序中的为“相对垃圾”呢?
三、垃圾回收
垃圾回收机制(GC,Garbage Collection
)负责在程序执行过程中回收无用的变量和内存占用的空间。一个对象虽然没有再次使用的可能,但是仍然存在于内存中的现象被称为内存泄漏。内存泄漏是非常危险的现象,尤其在长时间运行的程序中。如果一个程序出现了内存泄漏,它占用的内存空间就会越来越多,直至耗尽内存。
字符串、对象和数组没有固定的大小,所以只有当它们大小已知时才能对它们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都要分配内存才存储这个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便它们能够被再次利用;否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。
JavaScript
的垃圾回收机制会间歇性的检查没有用途的变量、对象(垃圾),并释放条它们占用的空间。
四、可达性(Reachability)
不同的编程语言采用不同的垃圾回收策略,例如C++
就没有垃圾回收机制,所有的内存管理靠程序员本身的技能,这也就造成了C++
比较难以掌握的现状。JavaScript
采用可达性管理内存,从字面意思上看,可达的意思是可以到达,也就是指程序可以通过某种方式访问、使用的变量和对象,这些变量所占用的内存是不可以被释放的。
JavaScript
规定了一个固有的可达值集合,集合中的值天生就是可达的:
- 当前正在执行的函数上下文(包括函数内的局部变量、函数的参数等);
- 当前嵌套调用链上的其他函数、它们的局部变量和参数;
- 全局变量;
- 其他内部的变量;
以上变量称为根,是可达性树的顶层节点。
如果一个变量或则对象,直接或者间接的被根变量应用,则认为这个变量是可达的。
换一个说法,如果一个值能够通过根访问到(例如,A.b.c.d.e
),那么这个值就是可达的。
五、可达性举例
层次关联:
let people = { boys:{ boys1:{name:'xiaoming'}, boys2:{name:'xiaojun'}, }, girls:{ girls1:{name:'xiaohong'}, girls2:{name:'huahua'}, }};