内存泄漏是什么?
内存泄漏是指程序再使用完内存后,没有释放该内存,导致内存控件无法再被其他程序使用的情况。当一个对象创建时,系统会为其分配一块内存空间,当对象不再被使用时,应该及时释放内存空间,以便其他对象可以使用。然而,如果程序中存在内存泄漏的情况,对象的内存空间没有被释放,就会导致内存的浪费和不足就叫内存泄漏。
垃圾回收机制
1、什么是垃圾回收机制?
Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存
原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存
2、常见的垃圾回收机制:
① 标记清除:这是JavaScript中最常用的垃圾回收算法。它通过标记不再使用的对象,然后清除它们占用的内存空间。垃圾回收器会从根对象开始,遍历所有可访问的对象,并标记它们。然后它们遍历堆中的所有对象,清除未标记的对象。
② 引用计数:这是一种简单的垃圾回收算法,它通过计算对象的引用数量来确定对象是否可以被回收。当一个对象的引用数量变为0时,说明它不再被使用,可以被回收。然而,引用计数算法无法处理循环引用的情况,因为循环引用的对象的引用数量永远不会变为0.
③ 分代回收:这是一种优化垃圾回收算法,他根据对象的生命周期将堆分为不同的代。一般来说,新创建的对象会被分配到新生代,而经过多次垃圾回收任然存活的对象会被晋升到老生代。分代回收算法可以根据对象的生命周期来选择合适的回收策略,提高垃圾回收的效率。
内存泄漏常见的有哪些?
未清理的定时器或回调:如果你创建了一个定时器或回调函数,但未正确清理它们,它们将继续存在于内存中,即使你不再需要它们。这样的情况可能导致内存泄漏。
被遗忘的事件监听器:当你添加事件监听器时,请确保在不再需要时将其删除。如果你忘记删除事件监听器,它们将保留对对象的引用,即使对象已经不再需要,也不会被释放。
循环引用:循环引用是指两个或多个对象之间相互引用,导致它们无法被垃圾回收器正确处理。这通常发生在两个对象互相持有对方的引用,并且没有其他的引用指向它们。
未释放的DOM对象:当你使用JavaScript操作DOM元素时,如果没有正确地释放对这些元素的引用,它们将一直存在于内存中。比如,使用全局变量引用DOM元素,即使你不再需要它,也不会被垃圾回收器释放。
闭包:闭包是指函数内部定义的函数可以访问其外部函数的变量。如果闭包持有对外部函数的一些变量的引用,并且这些变量是大型的对象或者函数,那么这些外部变量将无法被垃圾回收器释放。