一. 垃圾回收
浏览器常用的垃圾回收机制有两种:标记清除、分代垃圾回收、引用计数【几乎已经废弃,很少浏览器进行使用了】
JavaScript解释器可以检测到何时程序不再使用一个对象了,当它确定这个对象是无用的时候,他就知道不再需要这个对象了,就可以把它占用的内存释放掉了。
1. 标记清除【三色标记法】
JavaScript中有一个全局对象,定期的,垃圾回收器将从这个全局对象开始,找出所有从这个全局对象开始引用的对象,再找这些对象引用的对象...对这些活跃的对象标记,这是标记阶段。清除阶段就是清除那些没有被标记的对象。
问题: 在清除过后,内存空间会变得不连续,即会出现内存碎片。
解决: 采用 标记整理 ,区别于标记清除,只是标记结束后,标记整理法会将存活的对象向内存的一边移动,最后清理掉边界内存。
2. 分代垃圾回收
Chrome 使用分代垃圾回收机制,将内存分为
新生代和老生代两个代。新生代包含经常创建和短暂存在的对象,垃圾回收频率较高;而老生代包含存活时间较长的对象,垃圾回收频率较低。新生代使用的是更轻量级的回收算法(如Scavenge算法),而老生代使用的则是更复杂的回收算法(如Mark-Sweep、Mark-Compact等)。
二. 内存泄漏
内存泄漏(Memory Leak) 是指在程序中使用动态内存分配(例如 malloc、new 等)时,由于某些原因没有释放已分配的内存,导致可用内存减少,最终导致程序运行效率下降、甚至崩溃的现象。
内存泄漏的原因:
-
对象创建后没有及时释放:程序中创建了对象,但是没有及时释放对象所占的内存,使得对象所占的内存一直处于占用状态,最终导致内存不足。 -
代码无法访问到某些对象,导致无法释放:在程序中,运行时可能产生某些已经无法访问到的对象(例如因为没有正确的指针引用),这些对象的内存也无法被释放。 -
循环引用:在程序中,可能会出现对象之间形成的循环引用关系,使得这些对象的引用计数始终不为 0,导致这些对象的内存不能被正确的释放。
避免内存泄漏的一些方法:
- 避免循环引用
- 重复利用对象,可采用
对象池对对象进行管理!