Kolik paměti zabírá konkrétní aplikace?

7. 2. 2012 6:50 (aktualizováno) Petr Krčmář

Velmi často se v různých fórech objevují dotazy ohledně paměťové náročnosti Linuxu. Pokusím se jednoduše objasnit, jak se to má v systému s pamětí.

Pod mým článkem o programu Htop se jeden čtenář ptá, jak je to s ukazateli paměti v Linuxu. Je z nich pochopitelně zmatený, protože pochopení těch položek je poměrně komplikované. Zkusím tedy nastínit, co znamenají a jak s nimi pracovat.

Obecný základ

Abychom pochopili, která bije, potřebujeme určitý teoretický základ o procesech a jejich paměti. Každý proces může zabírat paměť na dvou místech: v RAM a ve swapu. Když systému dochází paměť, začne odkládat paměťové stránky z RAM na disk a tím ušetří systémovou paměť. Když chce proces danou paměťovou stránku použít, ta se automaticky načte zpět do RAM.

Linux šetří paměť. Takže pokud je některý kód potřeba vícekrát, je jeho paměť sdílena mezi více procesy. Paměť s binárním kódem je nastavena jen pro čtení, takže do ní nelze zapisovat a není problém ji tedy sdílet. Prakticky každý proces potřebuje systémovou knihovnu glibc, ta je mu tedy namapována, ale nekopíruje se. Zůstává v paměti jen jednou, ale ve svém virtuálním paměťovém prostoru ji vidí všichni.

Informace o zabrané paměti

Pokud se budete snažit z Linuxu vyrazit, kolik paměti doopravdy zabírá konkrétní proces, dostanete různé velmi rozdílné hodnoty, ze kterých zřejmě nebudete moudří. Tyto hodnoty zjistíte třeba pomocí ps, top či zmíněného htop. Obvykle jsou čtyři: VIRT, RES, SHR a SWAP. Někdy poslední z nich chybí, ale to teď není podstatné. Podstatné je, co která z nich znamená.

Jako příklad si ukážeme obrazovku Htopu, která ukazuje, kolik mi právě v paměti zabírá spuštěná Java:

VIRT – Virtual image

Ukazuje veškerou paměť namapovanou procesem. Je to zcela jistě nejvyšší číslo, které o procesu dostanete. Jeho součástí je totiž kód, data, sdílené knihovny, odswapované stránky i soubory namapované do paměti. Toto číslo bývá někdy velmi vysoké, jak je vidět i na příkladovém obrázku. Proces Java na něm zabírá více VIRT paměti, než kolik je jí zabráno celkově (horní graf). Proč?

Jak jsme si řekli, Linux šetří paměť a tak například namapované soubory rovnou nenatahuje do paměti, ale dělá to až ve chvíli, kdy jsou některé jejich části skutečně potřeba. V praxi si tak může proces klidně namapovat celý několikagigabajtový soubor a systém se bude tvářit, že je celý tento soubor v paměti. Teprve až proces sáhne doprostřed této paměti a zkusí něco přečíst, systém potřebnou stránku načte a dá data k dispozici. Položka VIRT tedy obsahuje i velikost dat, která v paměti doopravdy nejsou, ale proces si na ně může v případě potřeby sáhnout. Jinými slovy určuje velikost jeho virtuálního paměťového prostoru.

RES – Resident size

Ukazuje skutečnou velikost paměti, kterou proces zabírá v paměti RAM. Ale pozor, to rozhodně není číslo, které hledáme. Potíž je v tom, že část této paměti je sdílena mezi procesy, jak jsme si už řekli.

Pokud tedy budeme mít dva programy po 20 MB a oba budou linkovat stejnou knihovnu o velikosti 10 MB, budou mít jejich RES dohromady 60 MB, přestože v paměti budou všechny tyto části dohromady zabírat jen 50 MB, protože stejnou paměť knihovny budou mít namapovány oba procesy.

SHR – Shared memory

Tento ukazatel zobrazuje právě tu část paměti procesu, kterou sdílí ještě s dalšími procesy. V případě obou našich příkladových procesů by to bylo 10 MB.

SWAP

Konečně poslední ukazatel zobrazuje množství paměti procesu, které se nachází v odkládacím souboru. Tato hodnota není součástí hodnoty RES, protože ta ukazuje jen data v RAM.

Kolik paměti tedy zabírá konkrétní aplikace?

Na to je dost těžké odpovědět. Nejjednodušší je spočítat RES + SWAP – SHR. Tedy fyzicky zabranou paměť sečíst s odloženou částí a odečíst z ní sdílenou paměť. Tím dostaneme informaci o tom, kolik skutečného prostoru zabírá v RAM náš proces. Java z obrázku tedy reálně na paměťových čipech zabírá 178 MB, přestože má virtuálně namapován 1,2 GB.

Do těchto výpočtů ale nijak nezahrnujeme právě sdílenou paměť, která je sice k dispozici více procesům, ale v celkovém součtu obsazené paměti je nezanedbatelná. Můžeme se ale spokojit s tím, že tuto paměť nezabírá námi zkoumaný proces, protože by byla stejně zabraná kvůli potřebám jiného procesu. Snad jsem vám taje linuxové paměti alespoň trochu osvětlil.

Sdílet