JavaScript内存管理和垃圾回收
javascript与一些底层语言在内存处理方式有区别。底层语言有专门的内存管理接口如C语言
,需要手动跟踪处理内存的使用情况。JavaScript 具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存。但是这并不意味着javascript
开发者不需要去关心内存问题。 如果不了解内存管理机制,可能会造成内存泄露的情况。
内存生命周期 #
- 分配内存
- 使用分配到的内存(读、写)
- 不需要时将其释放\归还
内存的分配场景 #
下面我们来分析一下函数中局部变量的正常生命周期。
内存分配:局部变量只在函数执行的过程中存在。而在这个过程中,会为局部变量在栈(或堆)内存上分配相应的空间,以便存储它们的值。
内存使用:然后在函数中使用这些变量,直至函数执行结束。
内存回收:此时,局部变量就没有存在的必要了,因此可以释放它们的内存以供将来使用。大多数内存管理的问题都在这个阶段。在这里最艰难的任务是找到“哪些被分配的内存确实已经不再需要了”
javascript中的垃圾回收 #
- 对于在JavaScript中的字符串、对象、数组是没有固定大小的,只有当对他们进行动态分配储存时,解释器就会分配内存来储存这些数据,当JavaScript的解释器消耗完系统中所有的内存时,就会造成系统的奔溃
- 内存泄露: 在某些情况下,不再使用的变量所占用的内存没有及时的释放清理,导致程序运行中,内存越战越大,极端情况下会导致系统的奔溃,服务宕机。
- JavaScript有一套自己的回收机制,解释器可以检测到什么时候程序不再使用这个数据,就会把他所占用的内存释放掉。
通常,很容易判断变量是否还有存在的必要,但并非所有情况下都这么容易就能得出结论(例如:使用闭包的时)。垃圾收集器必须跟踪哪个变量有用哪个变量没用,对于不再有用的变量打上标记,以备将来收回其占用的内存。用于标识无用变量的策略可能会因实现而异,但具体到浏览器中的实现,则通常有两个策略:标记清除 和 引用计数。
基本所有语言第二部分都是明确的。第一和第三部分在底层语言中是明确的,但在像JavaScript这些高级语言中,大部分都是隐含的。
引用计数 #
一个对象如果有访问另一个对象的权限,叫做一个对象对另一个对象的引用。 引用计数算法把”对象是否在需要“简化为“对象有没有其他对象的引用”。 有个难以处理的问题: 当对象存在循环引用。引用计数算法考虑到他们相互都至少有一个引用,所以他们都不会被回收。
标记清除 #
这个算法吧“对象是否不再需要”简化为“对象是否可以获得”。
这个算法假定设置一个叫做根“root"的对象。垃圾回收期将定期从根开始,找所有从根来时引用的对象,然后找到这些对象引用的对象,从根来时,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。
通过这种算法,循环引用就不再是问题了。
限制: 那些无法从根对象找到的对象都将被清除。
版权属于: vincent
转载时须注明出处及本声明