簡體   English   中英

測量Linux上進程的內存使用情況

[英]Measuring memory usage of a process on Linux

我試圖測量linux上進程(java程序)的內存使用情況,並有兩個與此相關的問題:

  1. 我嘗試使用腳本ps_mem.py (來自/ proc / $ PID / smaps的值)和總內存使用量的峰值大約是135MB(私有和共享內存)。 共享內存量小於1MB。 嘗試使用Valgrind與valgrind --tool=massif --trace-children=yes --stacks=yes java myProgram工具valgrind --tool=massif --trace-children=yes --stacks=yes java myProgram在內存使用高峰時產生大約10MB。
    根據我的理解,堆是存儲程序變量的地方,這是否意味着兩種方法之間的差異是代碼本身所占用的空間(包括jvm)?

  2. 如果相同的程序有不同的RAM或/和使用不同的處理器(ARM或x86),它們是否在不同的機器上使用不同的內存量?

  1. 要看。
    • smaps中的許多共享內存映射smaps磁盤上的庫/二進制文件直接支持。 雖然它們的占地面積很重要,但它並不重要,因為系統可以隨時丟棄這些頁面,並在需要時再次從磁盤重新加載它們。
    • 任何臟的或私有的東西都只屬於當前進程(如果你的程序沒有高級分支,那么進程樹)。 這一點更為重要,因為如果需要將這些頁面推出內存,系統必須將它們保存為交換。
    • 測量的地塊可能與后者有關。 但是,JVM本身(沒有您的程序)所占用的內存都在兩者中。
  2. 是。 Java或它使用的庫可能會根據可用RAM的大小調整其內存模型。 在不同的體系結構中,您使用完全不同的二進制文件,這些二進制文件可能更大或更小,或者以不同的方式排列或使用不同的JIT和內存管理策略。

除此之外還有一個類似的問題,在這里回答同樣的問題,讓人們知道linux proc stat vm info目前是不准確的。
Valgrind可以顯示詳細信息,但它會顯着降低目標應用程序的速度,並且大多數時候它會改變應用程序的行為。

我假設每個人都想知道WRT“內存使用情況”如下......
在linux中,單個進程可能使用的物理內存量大致可分為以下幾類。

  • Ma匿名映射內存
    • .p私有
      • .d dirty == malloc / mmapped堆棧和堆棧分配和寫入的內存
      • .c clean == malloc / mmapped堆和堆棧內存一旦分配,寫入,然后釋放,但尚未回收
    • .s分享
      • .d dirty ==應該沒有
      • .c clean ==應該沒有
  • Mn命名映射內存
    • .p私有
      • .d dirty ==文件mmapped寫內存私有
      • .c clean ==映射程序/庫文本私有映射
    • .s分享
      • .d dirty ==文件mmapped寫入內存共享
      • .c clean ==映射庫文本共享映射

我更願意得到如下數字,以獲得最少開銷的實數。
你必須總結這些以便將ps顯示為RSS並且獲得更准確的數字而不要混淆。
/ proc /(pid)/ status嘗試顯示這些數字,但它們失敗了。
因此,我沒有嘗試將[anon],[stack]標記為正確地映射到每個映射,我的願望是linux內核人員將主要處理proc入口代碼以匯總並顯示這些Mapd,Mapc,Mnpd,....數字。
嵌入式linux的人會很高興恕我直言。

MAPD:

 awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Dirty/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps

MAPC:

 awk '/^[0-9a-f]/{if ($6=="") {anon=1}else{anon=0}} /Private_Clean/{if(anon) {asum+=$2}else{nasum+=$2}} END{printf "sum=%d\n",asum}' /proc/<pid>/smaps

Mnpd:......等等

對於#1,共享內存是由多個進程使用的內存(可能)。 這基本上是如果您在多個進程中運行相同的二進制文件或不同的進程正在使用共享庫。 堆是存儲已分配內存的位置(在Java中使用new時)。 由於Java有自己的VM,因此它會在您在java代碼中看不到的進程級別分配大量內存。 我認為是的,135 MB的大部分來自JVM代碼/數據本身。 但是,堆棧占用的內存(當您進行函數調用並具有局部變量時)也是如此。

對於#2,當我們讓內存等於RAM +交換空間時,不同數量的RAM不會影響使用多少“內存”。 但是,不同的處理器(特別是如果我們談論的是32位與64位)可能會使用不同的內存量。 此外,編譯進程的方式可能會改變使用的內存量,因為您可以指示編譯器優化內存占用超速,以及完全禁用部分或全部優化。

您可能想看看JConsole。 根據您的測量目的,事情可能會很棘手。 如果您想了解Java程序的內存使用情況,那么測量進程內存使用情況的工具將不准確,因為它們將顯示JVM和程序使用的內存。

至於massif工具,您應該知道JVM的某些部分將存儲在堆棧中,並且Java代碼本身可能在堆上(因為它是JVM的變量),我對JVM的了解還不夠說。

暫無
暫無

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

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