日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

javaScript 内存管理机制

發布時間:2024/4/11 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javaScript 内存管理机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

大家好,今天分享的主題為 JavaScript 內存管理機制,本次分享將從以下三部分進行講述:

  • js 內存管理與 js 垃圾

  • 常見的 GC 算法

  • V8 引擎的垃圾回收

js 內存管理與 js 垃圾

關于 JavaScript 內存管理機制,相信大家都有所了解。我們就簡單看一下 js 內存管理與 js 垃圾。JavaScript 內存管理是由 JS 自動操作的,不需要人為進行參與,這些內存管理包含以下三項:

  • 申請內存空間

  • 使用內容空間

  • 釋放內容空間

而 js 垃圾是指對象不在引用時、對象不能從根上訪問到時,都可以被稱為 js 垃圾。其他部分包括引用和可達對象這些大家肯定很熟悉了,我們就不再多說。下面我們談一談 GC 算法。

## GC 算法

GC 算法其實是為了找到內存中的垃圾,并釋放和回收空間。這里所說的的垃圾,是指算法中認為程序中不再需要使用的對象,與程序中不能訪問到的對象。

說回 GC 算法,這個是比較概念性的內容,我們簡單歸納一下。GC 是一種自內存中查找垃圾釋放空間、回收空間的一個垃圾回收器機制。算法則是工作時查找和回收所遵循的規則。常見 GC 算法有引用計數、標記清除、標記整理、分代回收。

引用計數

引用計數曾經主要用于 IE8 以下的瀏覽器,現在的瀏覽器已不再使用,因此只做簡單介紹。引用計數的基本原理是記錄跟蹤每一個值被引用的次數,被引用則計數加一,被釋放則減一,當數值為零時則代表該值所在內存已經不再使用,因此釋放所占空間。引用計數的優點是引用次數實時監控,所以回收垃圾能夠及時回收,從而最大限度減少程序暫??D時間。但也是因為一直在運作,所以資源消耗和時間開銷大,無法回收循環引用的對象。

標記清除

標記清除分為分為標記和清除兩個階段,其核心思想是遍歷所有對象,找標記活動對象,即前面提到的可達對象,清除沒有標記的對象,以及回收沒有標記對象的空間。

上圖是 global 的查找簡易流程圖。其中左側 A、B、C、D、E 表示可查到的對象,右側 a1、b1 表示循環引用對象。其中 a1 為引用計數,而因為引用計數一直在運作,無法回收循環引用的對象的缺點,可以反向找到正在循環引用的對象。

這也是標記清除的優點,可以解決對象循環的引用回收問題。但是標記清除的缺點是空間碎片化,無法及時回收垃圾對象。因為它需要先標記再清除,不能像引用計數一樣對值進行實時監控,因此無法讓空間最大化使用。通過下圖可以簡單看一下標記清除的空間碎片化特點。

標記整理

上面提到標記清除有空間碎片化的缺點,而標記整理優化了這個缺點。從名字也可以聯想到,標記整理是標記清除的增強。標記整理在標記階段的操作和標記清除一致,但是在清除階段會先執行整理,再進行清除。這種方式能夠有效減少碎片化空間。和標記清除一樣,標記整理也不能實時回收垃圾對象。

我們通過下面三張圖對標記整理進行一個簡單直觀的了解。

可以看到在進行垃圾回收前,活動空間和非活動空間是混雜的。而在確定進行回收后,標記整理會對空間進行歸類整理,將活動空間和非活動空間統一整理到一起,形成下圖的結果:

之后再進行標記清除就能夠避免回收操作避免出現大量碎片化空間,讓空間最大化應用。

看完了 GC 算法,以 V8 引擎為例我們具體來看一下 GC 算法在 JS 垃圾回收里的使用。

V8 引擎的垃圾回收

V8 是一款當下較為主流 JavaScript 執行引擎,采用即時編譯,處理速度很快。V8 的內存是設限的,比如 64 位操作系統的上限是 1.4T,下限是 700M,32 位操作系統的上下限分別為 64M 和 32M。

V8 采用分代回收的垃圾回收策略,將內存分為新生代和舊生代兩種,并對不同的對象采用不同的對應算法。

上圖是 V8 的內存分配示意圖,可以清除看到 V8 內存空間分為兩部分。左邊的 from 和 to 是新生代,占用的空間比較小(32M|16M),這里的新生代指的是存活時間短的存儲區。右邊紅色的部分則是存活時間較長的老生代存儲區。

V8 常用的 GC 算法有以下 5 種:

  • 分代回收

  • 空間復制

  • 標記清除

  • 標記整理

  • 標記增量

這其中新生代采用復制算法和標記整理進行垃圾回收,老生代使用標記清除、標記整理和增量標記進行垃圾回收。

V8 新生代對象回收實現

上圖為 V8 新生代對象回收實現圖,采用復制算法和標記整理結合的方式進行垃圾回收。新生代內存區的兩個等大空間,From 代表使用空間用于存儲活動對象,To 代表空閑空間。V8 的新生代對象回收是通過標記整理將對象完成整理后拷貝到 To,然后將 To 和 From 進行空間交換,并釋放整理后的無用對象所占空間。需要注意的是,在將整理對象拷貝到 To 時可能會出現晉升。晉升指的是將新生代對象移動至老生代存儲區。晉升通常有兩個條件,其一是在進行一輪 GC 后還活著的新生代對象可以晉升,其二是 To 空間的使用率超過 25%。

V8 老生代對象回收實現

V8 老生代的回收過程采用標記清除、標記整理和標記增量結合的方式。一般在進行垃圾回收時會通過標記清除完成垃圾空間的回收,但是當新生代移動到老生代,而老生代內存不夠時,則會通過標記整理進行空間優化,并使用增量標記進行效率優化。

標記增量其實是通過對標記操作進行標記的方法,讓時間安排變得合理。這句話可能有些繞,簡單說就是在垃圾回收時,讓標記系統在標記時分出不同的時間段,分別進行標記和執行,讓二者的操作間隔開,從而優化時間安排,這會讓頁面在體感上更為順暢。

總結

以上是生活随笔為你收集整理的javaScript 内存管理机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。