内存管理是所有语言都会涉及到的一个重要内容,在javascript中同样也需要管理,不同的是javascript这个高级语言在内存管理上是无感知的,就是引擎会帮我们自动管理内存。
内存管理
我们在创建一个对象变量的时候经历了内存管理
- 创建对象(开辟内存空间)
- 声明变量引用对象(对象内存地址引用)
- 调用对象
- 将变量设置为其他数据或对象(原对象不可访问、不可引用、不可达,其内存将被回收)
垃圾收集器
垃圾收集器的类型:
- 标记-清除:最初JavaScript引擎中使用的方法,先给所有活动对象打上标记,然后回收未标记的对象。
- 引用计数:每个对象维护一个引用计数,当计数为0时回收对象。但是这种方法有循环引用的问题,后来被淘汰。
- 分代收集:根据对象的存活时间将堆分为不同的代,对不同的代使用不同的算法以优化性能。
内存泄露
在JavaScript中,内存泄露是指由于某些原因导致内存无法被垃圾回收器(GC)回收,从而导致应用程序占用的内存持续增长。那么有哪些情况可能是会导致内存泄露,需要我们在开发中注意的呢:
- 意外的全局变量:在函数内部,如果使用未声明的变量或使用this关键字(当它指向window对象时),可能会不小心创建全局变量,而这些全局变量不会被回收。
- 闭包引起的内存泄漏:闭包可以访问创建时的作用域中的变量,即使这些变量在函数执行完毕后仍然被闭包引用,导致无法被垃圾回收。虽然闭包有众多好处,但也不能滥用。
- 没有清理的DOM元素引用:如果在一个全局变量或长时间存活的对象中引用了DOM元素,即使该DOM元素从页面中移除,由于仍有引用存在,它也不会被垃圾回收。
- 被遗忘的定时器或回调:如果设置了定时器或者注册了事件监听器,而没有在适当的时候取消它们,这些回调函数会持续占用内存。
- 循环引用:在某些情况下,对象之间形成循环引用,如果没有外部引用指向它们,这些对象可能不会被垃圾回收。
- 缓存数据未清理:如果应用程序中使用了缓存机制,而缓存数据没有在不再需要时被清理,这也可能导致内存泄漏。
- 未释放的事件监听器:如果为元素注册了事件监听器,并且在元素不再使用时没有移除这些监听器,这也可能导致内存泄漏。
- 遗留的Web动画或请求:例如,如果启动了一个Web动画或网络请求,并且在不再需要时没有取消或终止它们,它们可能会持续占用内存。