内存泄漏
什么是内存泄漏
内存泄漏指的是程序中由于错误或不良的内存管理而导致未使用的内存无法被释放的情况。
引起内存泄漏原因
-
对象的引用未被正确释放:当一个对象不再需要时,如果其引用仍然存在,即使你不再使用它,它也无法被垃圾回收器回收。
-
定时器未被清除:如果你创建了定时器或周期性任务,但在不再需要时忘记清除它们,这些任务会持续占用内存直到页面关闭。
-
全局变量:全局变量会一直存在于内存中,如果某个对象被赋给了一个全局变量,即使在局部作用域中不再使用该对象,它仍然会被保留在内存中,直到应用关闭。
-
循环引用:当两个或多个对象相互引用,并且它们之间的引用形成了一个闭环,即使这些对象不再被外部引用,它们之间的引用关系会阻止垃圾回收器将它们清理掉。(只出现在"引用计数垃圾回收",从2012年所有现代浏览器都使用了标记 - 清除垃圾回收算法,所以循环引用不再是问题了)
垃圾回收机制
引用计数垃圾回收
这是最初级的垃圾收集算法。此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。
标记 - 清除垃圾回收算法
标记-清除算法(Mark and Sweep Algorithm)是一种常见的垃圾回收算法,用于在程序运行过程中自动管理内存。该算法通常由两个阶段组成:标记阶段和清除阶段。
-
标记阶段:
- 从根节点开始(根节点是全局对象或者被全局对象直接引用的对象),通过遍历对象之间的引用关系,标记所有可以访问到的对象。
- 被标记的对象被认为是活动对象,而未被标记的对象被认为是垃圾对象。
-
清除阶段:
- 在清除阶段,垃圾回收器会遍历堆内存中的所有对象,如果某个对象没有被标记为活动对象,则被认为是垃圾对象,将其所占用的内存释放。
- 清除后的对象可以被重新使用,或者当需要新的内存空间时,可以用来分配新对象。
标记-清除算法的优点是简单且有效,能够正确地识别出不再使用的内存,并将其释放。然而,该算法也存在一些缺点,如在执行清除阶段时可能会造成内存碎片化,影响内存分配的效率。