以下術語用於 記憶體工具, 用於調查記憶體問題。 這些記憶體術語適用於一般的記憶體分析,以及像 Java 或 .NET 等語言的記憶體剖析工具。
欲了解更多使用 記憶體 工具的資訊,請參閱 使用記憶體工具記錄堆積快照 (「堆積快照」剖析類型) 。
記憶體圖
可以把網頁使用的記憶體想像成一個圖:一個包含由邊連接的節點的結構:
記憶體圖中的節點代表頁面所使用的物件,包括原始型別如 JavaScript 數字或字串,以及物件如關聯陣列。 記憶體圖中的節點與邊會被賦予以下標籤:
節點 (或 物件) 會以建 構 函式名稱來標示。
邊 會以 屬性名稱來標示。
圖中的節點可以有兩種方式儲存記憶體:
直接;記憶由物件本身所持有。
隱含地,透過保留對其他物件的參考。 持有其他物件參考的物件可以防止這些物件被垃圾回收 (GC) 自動丟棄。
JavaScript 堆積與渲染器記憶體
JavaScript 堆積是瀏覽器程序中的一個記憶體區域,所有 JavaScript 與 WebAssembly 物件都存在於此。 JavaScript 堆積也被稱為 V8 記憶體 (,得名於驅動 Edge) 的 V8 JavaScript 引擎Microsoft。
JavaScript 堆積是渲染器記憶體的一部分。 渲染器記憶體是瀏覽器處理網頁渲染過程中所使用的記憶體。 渲染器記憶體由以下部分組成:
- 原生記憶體,例如代表 DOM 節點的 C++ 物件所使用的記憶體。
- JavaScript 堆疊記憶體。
- JavaScript 堆積記憶體,包含所有由頁面啟動的專用工作者。
記憶工具同時顯示:
- V8 記憶體。
- 這些物件是本地記憶體中分配且與渲染網頁相關的物件。
垃圾回收的根源
垃圾回收 根 (GC 根) 由瀏覽器在從原生程式碼引用到 V8 虛擬機外的 JavaScript 物件時產生。 這些參考稱為handle(handles)。
GC 內部有許多根源,但大多數對網頁開發者來說並不有趣。 從網頁的角度來看,存在以下幾種 GC 根:
視窗全域物件 (每個 iframe) 。
有時物件會被 由來源 或 主控台 工具設定的除錯上下文保留,例如在 主控台 工具中評估 JavaScript 表達式時。 要從 記憶體 工具中移除這些物件,在錄製堆積快照前,先清除 主控台 工具並在 來源 工具中停用斷點。
記憶體圖以 GC 根開始,該根可以是 window 瀏覽器的物件,也 Global 可能是 Node.js 模組的物件。 你無法控制根物件如何被垃圾回收:
無法從根節點存取的節點可能會被垃圾回收。
物體大小與距離
記憶體工具顯示以下資訊欄位:
- 距離欄
- 淺尺寸欄位
- 保留尺寸欄位
以下將介紹這些欄位。
Distance (距離)
JavaScript 堆積中物件的 距離 是物件與 GC 根之間最短路徑上的節點數量。 距離越短,該物件在網頁記憶體使用中扮演重要角色的可能性就越高。
淺尺寸
淺層大小是指由物件直接持有的 JavaScript 堆積大小。 物件的淺大小通常很小,因為 JavaScript 物件通常只會將物件的描述,而非值,儲存在物件直接儲存的記憶體中。 大多數 JavaScript 物件的值會儲存在 JavaScript 堆積中其他位置的 備份儲存 庫,並且只會在該物件直接擁有的 JavaScript 堆積部分暴露一個小型包裝物件。
然而,即使是小型物件,也能間接承載 大量記憶體,透過防止垃圾回收過程丟棄其他物件。
淺大小欄中的數字是位元組數。
保留尺寸
保留大小是指物件隱含持有的記憶體大小,當物件及其他現有保留器以及所有從 GC 根無法到達的相依物件被刪除後,這些記憶體可能會被釋放。
也就是說,物件的保留大小是指如果將物件及其所有相依物件從記憶體圖中移除,所獲得的記憶體量。
保留的尺寸不能比淺尺寸小。
當一個物件被多個節點保留時,物件的大小會顯示在保持 GC 根的最短路徑保留節點的保留大小中。
保留大小欄位中的數字是位元組數。
侍從
物件的 保留器 是其他持有該物件參考的物件。 記憶體工具的保留器區塊會顯示包含摘要檢視中所選物件參考的物件。
記憶工具的「保留器」部分預設是依距離排序,這表示物件最簡單的保留路徑會先顯示。
任何沒有保留器的物件都可以被瀏覽器的垃圾回收器丟棄,從而減少記憶體使用。
V8 細節
在分析記憶體時,了解堆積快照為何會呈現某種樣貌是很有幫助的。 本節說明 V8 JavaScript 虛擬機 (簡稱 V8 VM,或簡稱 VM) ,如何將某些物件儲存在 記憶體中, 這有助於你在記憶體工具中分析堆積快照。
JavaScript 原語
在 JavaScript 中,有幾種原始類型,例如:
- 數字 (
3.14159如) 。 - 布林運算 (
true或false) 。 - 弦 (如
"Werner Heisenberg") 。
原語無法參考其他值,且始終是葉節點, (也稱為記憶體圖) 的終止節點 。
數字 可以儲存為以下兩種形式:
即時的31位元整數值稱為 小整數 (SMI) 。
堆積物件,稱為 堆積數。 堆積編號用於儲存不符合 SMI () 小整數的值,例如
double類型 ,或當需要封框的值,例如設定屬性時。
字串 可儲存在以下任一中:
VM 堆疊。
在 渲染器的記憶體中外部。 包裝 物件 被建立並用於存取外部儲存,例如從網路接收的腳本原始碼及其他內容會儲存在其中,而非複製到 VM 堆積中。
JavaScript 物件
新 JavaScript 物件的記憶體由專用的 JavaScript 堆積 (或 VM 堆) 分配。 這些物件由 V8 虛擬機的垃圾回收器管理,因此只要至少有一個參考資料,這些物件就會保持活躍。
其他物件
原生物件:任何不儲存在 JavaScript 堆積中的物件稱為 原生物件。 與堆積物件不同,原生物件不會由 V8 垃圾回收器在其整個生命週期中管理,且只能透過 JavaScript 包裝物件從 JavaScript 存取。
串接字串:在 JavaScript 中,因字串串接而被儲存並連接的字串,在 V8 中則以串接字串形式儲存。 字串內容的連接僅在需要時進行,例如需要建構連接字串的子字串時。
例如,如果你將
a和b連接起來,你會得到一個串接的字串(a, b),代表串接的結果。 若你之後將該結果串c接,則得到另一串((a, b), c)串:。陣列: 陣列 是一種具有數字鍵的物件。 陣列在 V8 虛擬機中被廣泛使用,用於儲存大量資料。 像字典一樣使用的鍵值對集合以陣列形式實作。
典型的 JavaScript 物件僅儲存為兩種陣列類型之一:
- 一個用來儲存命名屬性的陣列。
- 一個用來儲存數字元素的陣列。
當屬性數量較少時,屬性會儲存在 JavaScript 物件內部。
系統/地圖:描述其物件類型及佈局的物件。 例如, 系統/映射 物件用來描述隱含的物件階層結構,以快速存取屬性。 請參見 V8 中的快速性質。
注意事項
本頁部分內容基於 Google 創作與 分享 的作品,並依 據創用CC 姓名標示 4.0 國際授權條款進行修改。 原始頁面 可在此找到 ,作者為Meggin Kearney。
本作品採用 創用CC 姓名標示4.0國際授權條款授權。