簡體   English   中英

監視器未顯示正確的內存使用情況

[英]Monitor not showing the right memory usage

我想知道如何使用資源監視器、任何類型的htop top等來跟蹤進程的內存使用情況。 讓我們編寫一個簡單的 C 程序。

int main() {
    while(1){}
    return 0;
}

編譯后可執行輸出a.out只有16Kb

$ ls -lah ./a.out                                                                                                                                           [8:43:44]
-rwxr-xr-x  1 user  staff    16K May 17 08:43 ./a.out

據我了解,該代碼沒有變量,沒有malloc和各種需要使用除代碼本身之外的任何額外內存使用的語句,這些語句將在運行時加載到內存中。 堆棧指針、幀指針等的一些額外內存是預期的,但不應太多。

有趣的是,當我運行代碼時。 系統監視器給出了非常不同的意見。

所以我使用的是 MacOS,顯示器顯示虛擬內存使用量為30Gb+ MacOS System Monitory 的屏幕截圖,顯示正在運行的進程消耗 30.54Gb 內存的使用情況

好嗎?! 這可能是由於一些優化,或者 MacOS 管理內存的一些獨特技術。 讓我們嘗試在具有 1Gb 內存的 Ubuntu 虛擬機中運行它。

Ubuntu中top命令的屏幕截圖,其中進程消耗2356kb內存

我知道這看起來比 30Gb 更合理,但是 2356Kb?

我看錯了指標嗎?

據我了解,該代碼沒有變量,沒有 malloc 和各種需要使用除代碼本身之外的任何額外內存使用的語句,這些語句將在運行時加載到內存中。

你的代碼沒有太多; 但是您的代碼通常與一些啟動代碼鏈接,這些代碼執行預處理命令行參數、初始化 C 庫的部分以及調用您的main()等操作。

您還將有一個消耗內存(無論您是否使用它)的堆棧(例如,以便啟動代碼可以調用您的main() )。

當您的程序啟動時,可執行加載器還將“加載”(映射到您的虛擬地址空間)任何共享庫(例如 C 標准庫,這可能是您未編寫的啟動代碼所需要的,即使您不使用自己做)。

可能發生的另一件事是,當啟動代碼初始化 C 標准庫時,C 標准庫可以初始化堆(對於malloc()之類的東西)和一些東西(C 標准庫初始化的其余部分,C 標准庫的其余部分)啟動代碼)可以使用malloc()即使您沒有編寫的代碼不使用它。

當然操作系統/虛擬內存管理使用頁面; 所以程序的每個部分( .text.data等)、每個共享庫中的每個部分、堆棧、堆等的大小; 向上舍入到頁面大小。 根據它是哪台計算機,頁面大小可能為 4 KiB(最近的 ARM/M1 Apple 機器為 16 KiB); 如果您沒有創建的啟動代碼需要.data部分中的 1 個字節,則它需要 4 KiB(或 16 KiB)的內存。

所以我使用的是 MacOS,顯示器顯示虛擬內存使用量為 30Gb+!

我猜大部分是為堆分配的空間; 使用了少量空間而大部分沒有使用的地方。 如果您假設有 176 KiB 的私有內存(由您的程序及其啟動代碼使用)和 440 KiB 的共享內存(由共享庫使用),並假設“32.54 GiB”為 3412000000 KiB; 那么它可能是“3412000000 - (176 + 440) = 3411999384 KiB 的空間已分配但實際上並未被使用”。

我知道這看起來比 30Gb 更合理,但是 2356Kb?

繼續假設它主要是“已分配但未使用”的堆空間; 了解堆是如何工作的很好。 “已分配但未使用”的空間幾乎沒有成本,但要求操作系統分配空間(例如,因為程序實際使用了所有空間並且用完了“已分配但未使用”的空間)會產生一些開銷。 出於這個原因,C 庫傾向於向操作系統詢問大塊“已分配但未使用”的空間(通過減少需要向操作系統詢問更多空間的機會來最小化開銷),然后在您使用時將其拆分為小塊調用malloc()

考慮到這一點; 並且不要忘記啟動代碼和庫是“通用的”,不太可能專門針對任何一個程序進行優化; 您可以說堆的“已分配但未使用”空間的最佳大小無法確定,但范圍從“可能太小但無關緊要”到“可能太大但沒人關心”。 不同的編譯器和/或庫和/或操作系統做出不同的決定; 因此“已分配但未使用”的空間量會有所不同。

我看錯了指標嗎?

我不知道(這取決於您開始查看內存統計信息的原因)。

在現代機器上,總虛擬地址空間可能是 131072 GiB(其中大部分是“未分配”),所以如果您擔心“已分配但未使用”空間會導致您用完“未分配”空間稍后您將看到正確的指標。

通常,人們更關心(某些子集)“分配和實際使用的空間”。

如果您擔心消耗過多的實際 RAM(例如,擔心會增加操作系統使用交換空間的機會,這可能會降低所有軟件的性能,而不僅僅是您的軟件),那么您需要查看“實際內存大小"; 但我懷疑這包括共享內存(許多程序會使用它,而不僅僅是你的程序)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM