Jelenlegi hely
Memóriahasználat ellenőrzése smaps-sal
Sok esetben hasznos lehetne megismernünk egyes futó programjaink tényleges aktuális és maximális memória használatát. Memóriával kapcsolatos kérdésekkel általában nem foglalkozunk, mert általános hozzáállás szerint úgyis akad elég a vasban és nem kell emiatt aggódni, de ennek ellenére adódhatnak olyan helyzetek amelyeknél hasznos ha fel vagyunk fegyverkezve a megfelelő eszközökkel és ismeretekkel.
A memória használat ellenőrzésének egyik legegyszerűbb kézenfekvő módja, hogy elindítjuk a top programot és ott a megfelelő processznél figyeljük a RES oszlopot. Ez az aktuális Resident Set Size-t mutatja, tehát a programunk által foglalt memória méretét. (A maximális memóriahasználat mérésére ebben az írásban nem térek ki.)
De mi is ez az RSS valójában?
- Kód terület mérete
- Adat terület mérete
- Heap foglalás
- Stack méret
- Shared library-k (megosztott könyvtárak so-k) mérete
A probléma az utolsó pontban felsorolt shared library-kal van, ugyanis ezek, mint a nevéből is kiderül megosztott erőforrásként állnak rendelkezésre a processzeknek és csak egyszer kerülnek betöltésre a memóriába.
Vegyük például azt az esetet, hogy futtatjuk az Operát és a Firefoxot egymás mellett (tfh. az egyikben flash filmeket nézünk a másikban meg csak böngészünk, ez most majdnem lényegtelen) mindkét alkalmazás használja a png shared library-t, ami png típusú képek megjelenítésére nyújt szolgáltatást, akkor a png library mérete a top program RSS részébe mindkét alkalmazásnál külön-külön bele van számolva, holott a memóriába csak egyszer van betöltve, így csak egyszer foglal helyet.
Ezen a ponton akkor fel is tehetjük a kérdést, hogy mit tekintünk akkor egy processz tényleges memória fogyasztásának?
Ezt a kérdést nem lenne célszerű megválaszolni, mert nincs rá egyértelműen helyes válasz; a körülményekhez mérten kell eldönteni mit akarunk számolni, hogy a shared library-k által fogyasztott memóriát hozzászámoljuk-e minden programhoz, vagy sem? Vagy ne is számoljuk egyikhez sem?
Milyen lehetőségeink vannak a memória részletes feltérképezésére?
A Linux 2.6.14-es Kernelétől a proc filerendszerbe új szolgáltatásaként bevezetésre került a smaps melyben minden processz aktuális memória-címtartományáról kapunk részletes információkat a /proc/PID/smaps filejában. Ezen információkat felhasználva és rendszerezve szét tudjuk választani a Heap és Stack használatot, illetve a különböző shared library-k által foglalt memóriát; több processz futtatása esetén vizsgálhatjuk a megosztott területen lévő és nem megosztott területen lévő könyvtárak (library-k) fogyasztását is.
Első ízből tekintsünk bele a nyers smaps file felépítésébe:
# cat /proc/1/smaps 08048000-080cf000 r-xp 00000000 08:04 4554884 /sbin/init Size: 540 kB Rss: 260 kB Pss: 260 kB Shared_Clean: 0 kB Shared_Dirty: 0 kB Private_Clean: 260 kB Private_Dirty: 0 kB Referenced: 120 kB Swap: 0 kB (...)Első ránézésre elég bizarr, de azért nézzük meg az érdekesebb adatokat: Az első oszlop a címtartományt mutatja hexa értékben, a második oszlop a címtartományhoz való hozzáférés jogosultságait (kód szegmens r-, adat szegmens rw), a hatodik oszlop pedig a bináris vagy shared library elérési helyét. A sorok közül az Rss mező az érdekes, ez a library vagy bináris tényleges memóriafoglalása. A smaps file-ból önmagában elég sokáig tart kibogarászni az információkat, de szerencsére már volt aki alkotott egy értelmezést segítő perl modult a smapshoz mely a perl CPAN gyűjteményében Linux::Smaps néven elérhető avagy letölthető/telepíthető innen: http://search.cpan.org/~opi/Linux-Smaps-0.06/lib/Linux/Smaps.pm A perl modullal már egyszerűen készíthetünk értelmezőt a smaps filehoz, de perl tudás hiányában se keseredjünk el, mert más már készített előttünk ilyet: http://www.contrib.andrew.cmu.edu/~bmaurer/memory/smem.pl Utóbbi program egyszerűbb kis saját kutatásainkhoz teljesen tökéletes. Nézzük a kimenetét:
$ smem2.pl 4445
VMSIZE: 24456 kb
RSS: 14552 kb total
11220 kb shared
424 kb private clean
2908 kb private dirty
PRIVATE MAPPINGS
vmsize rss clean rss dirty file
1952 kb 0 kb 1892 kb [heap]
252 kb 0 kb 252 kb /usr/lib/qt-3.3.8b/lib/libqt-mt.so.3.3.8
176 kb 0 kb 176 kb /usr/lib/libkdeui.so.4.2.0
68 kb 0 kb 68 kb /usr/lib/libkdecore.so.4.2.0
84 kb 0 kb 36 kb [stack]
324 kb 0 kb 28 kb /usr/lib/libGL.so.1.2
16 kb 0 kb 16 kb
(...)
SHARED MAPPINGS
vmsize rss clean rss dirty file
6536 kb 3960 kb 0 kb /usr/lib/qt-3.3.8b/lib/libqt-mt.so.3.3.8
2744 kb 1824 kb 0 kb /usr/lib/libkdeui.so.4.2.0
2188 kb 1488 kb 0 kb /usr/lib/libkdecore.so.4.2.0
1300 kb 548 kb 0 kb /lib/libc-2.7.so
(...)
A kcalc-t kimentének egy részletét választottam, természetesen tetszőleges programnak le lehet kérdezni a "memória térképét".
- A kimenet első részében egy összegzést olvashatunk a memóriahasználatról.
- VMSIZE az a címtér amelyet a program használ, de mivel ez a virtuális címtartományt jelenti, így nincs feltétlen ténylegesen használt memória mögötte.
- Az RSS avagy a resident set size a ténylegesen elfoglalt memóriát mutatja, szerencsére több komponensre van osztva, így megtudhatjuk, hogy mennyi más processzekkel közösen használt könyvtárak (shared) memória igénye és mennyi a ténylegesen csak a programunk által fogyasztott memória (private clean/dirty).
- A Private mappings részben látjuk azokat a könyvtárakat (+ heap, + stack) és memória-használatukat, melyeket a program csak egyedül használ. (Amennyiben egy területnek nincs elérési útja úgy a heap-hez tartozik.)
- A Shared mappings részben pedig más futó programokkal közösen használt könyvtárakat láthatjuk felsorolva.
- A hozzászóláshoz regisztráció és belépés szükséges

Hozzászólások
Köszi ez nagyon hasznos volt!
Köszi ez nagyon hasznos volt! :)