什么是垃圾回收
垃圾回收是指一種自動內存管理機制,當聲明一個變量時,會在內存中開辟一塊內存空間用于存放這個變量。當這個變量被使用過后,可能再也不需要它了,此時垃圾回收器會自動檢測并回收這些不再使用的內存空間。垃圾回收的主要目的是釋放不再使用的內存,提高內存的使用效率,避免內存泄漏。
垃圾回收的兩種算法
標記清除算法
標記清除算法的工作過程可以分為兩個階段:
標記階段
:從根對象(在JS中就是全局對象)開始,遍歷所有可達的對象,并標記它們。
清除階段
:清除所有未被標記的對象,這些對象被認為是"垃圾",可以被安全地回收。
這個過程可以想象成從根部溢出一大桶油漆,油漆流經所有引用并標記所有可達的對象。然后移除未被標記的對象
引用計數算法
引用計數算法的工作原理如下:
- 每當有一個新的引用指向該對象時,計數加一。
- 當引用被刪除或重新賦值時,計數減一。
- 當計數為零時,表示該對象不再被任何其他對象引用,可以被安全地回收。
引用計數算法的優點是能夠在對象變成垃圾的那一刻立即回收,不需要等待定期掃描。然而,它無法處理對象之間的循環引用問題,容易導致內存泄漏
兩種算法比較
標記清除算法和引用計數算法各有優缺點:
標記清除算法:
優點:能夠處理對象之間的循環引用問題
缺點:可能導致性能問題,需要定期掃描整個內存空
引用計數算法:
優點:能夠在對象變成垃圾的那一刻立即回收
缺點:無法處理對象之間的循環引用問題,容易導致內存泄漏
V8引擎的垃圾回收機制
分代式垃圾回收機制將內存分為新生代和老生代兩部分:
新生代:處理短期存活的對象,內存最大值在64位系統和32位系統上分別為32MB和16MB。新生代又會分為兩個半區(from和to兩個區)
老生代:處理長期存活的對象。
新生代垃圾回收
當新生代的from空間快達到上限時,會觸發一次垃圾回收。垃圾回收器會從根部開始遍歷,不可達對象(即無法遍歷到的對象)將會被回收,并把空間中的剩余對象移動到to空間。最后把from空間清空。
此時to空間變成新的from空間,from空間變成新的to空間。
新生代=》老生代
如果對象在新生代中存活了一定次數(通常是15次),它會被晉升到老生代。
老生代垃圾回收
當老生代的內存空間快達到上限時,V8引擎使用標記-清除(Mark-Sweep)、標記-壓縮(Mark-Compact)算法。
- 把老生代所有的對象標記成0,并把可達的對象標記成1
- 清除0的對象
- 把剩余的對象標記置0
- 并用標記-壓縮算法將位置重新排序變得緊密