Analiza zużycia pamięci w programach w systemie Linux z narzędziem memusage

System operacyjny Linux dostarcza szeroki wachlarz narzędzi do monitorowania i zarządzania zasobami systemowymi. Jednym z nich jest memusage, które umożliwia analizę zużycia pamięci przez aplikacje i procesy uruchomione w systemie. W tym artykule przyjrzymy się funkcjonalności tej komendy, sposobom jej użycia oraz interpretacji wyników.

Wprowadzenie do memusage

memusage to narzędzie monitorujące użycie pamięci przez procesy w systemie Linux. Jest częścią pakietu GNU Binutils i dostarcza szczegółowe informacje o alokacji oraz zwalnianiu pamięci dynamicznej przez aplikacje.

Program ten jest szczególnie użyteczny dla programistów i administratorów systemowych, którzy chcą zoptymalizować wydajność aplikacji oraz wykrywać potencjalne wycieki pamięci.

Instalacja memusage

W większości dystrybucji Linux memusage jest dostępne jako część pakietu GNU Binutils. Możesz go zainstalować za pomocą menedżera pakietów odpowiedniego dla Twojej dystrybucji:

  • Debian/Ubuntu:
    • sudo apt install binutils
  • Fedora:
    • sudo dnf install binutils
  • Arch Linux:
    • sudo pacman -S binutils

Po instalacji możesz zweryfikować dostępność komendy za pomocą:

$ memusage --help
Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
Profile memory usage of PROGRAM.

   -n,--progname=NAME     Name of the program file to profile
   -p,--png=FILE          Generate PNG graphic and store it in FILE
   -d,--data=FILE         Generate binary data file and store it in FILE
   -u,--unbuffered        Don't buffer output
   -b,--buffer=SIZE       Collect SIZE entries before writing them out
      --no-timer          Don't collect additional information through timer
   -m,--mmap              Also trace mmap & friends

   -?,--help              Print this help and exit
      --usage             Give a short usage message
   -V,--version           Print version information and exit

 The following options only apply when generating graphical output:
   -t,--time-based        Make graph linear in time
   -T,--total             Also draw graph of total memory use
      --title=STRING      Use STRING as title of the graph
   -x,--x-size=SIZE       Make graphic SIZE pixels wide
   -y,--y-size=SIZE       Make graphic SIZE pixels high

Mandatory arguments to long options are also mandatory for any corresponding
short options.


For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.

3. Podstawowe użycie memusage

Aby uruchomić program i monitorować jego zużycie pamięci, wystarczy poprzedzić polecenie memusage nazwą programu:

$ memusage ./nazwa_programu.bin

Przykładowo, jeśli chcesz sprawdzić zużycie pamięci przez skrypt Python:

$ memusage python skrypt.py

Po uruchomieniu komendy memusage generuje graficzny raport w formie okna X11, które przedstawia użycie pamięci dynamicznej przez proces.

Analiza wyników memusage

Raport generowany przez memusage zawiera kilka kluczowych elementów:

  • Całkowite użycie pamięci – łączna ilość przydzielonej pamięci.
  • Ilość zwolnionej pamięci – pamięć, która została poprawnie zwolniona.
  • Wykres użycia pamięci – graficzna reprezentacja zmian w alokacji pamięci w czasie działania programu.
  • Szczegółowe statystyki – dane dotyczące liczby wywołań funkcji malloc(), free() oraz innych operacji związanych z pamięcią dynamiczną.

Przykłady zastosowania memusage

a) Debugowanie wycieków pamięci

Wyciek pamięci występuje wtedy, gdy program rezerwuje pamięć, ale nigdy jej nie zwalnia. memusage pozwala łatwo wykryć takie sytuacje poprzez analizę wykresu zużycia pamięci.

b) Optymalizacja aplikacji

Programiści mogą używać memusage do porównania efektywności różnych algorytmów pod kątem użycia pamięci, co umożliwia lepsze zarządzanie zasobami i poprawę wydajności aplikacji.

Przykład działania z kodem programu w języku C

Kod programu testowego

#include <stdio.h>
#include <stdlib.h>

#define CYCLES 20

int
main(int argc, char *argv[])
{
   int i, j;
   size_t size;
   int *p;

   size = sizeof(*p) * 100;
   printf("malloc: %zu\n", size);
   p = malloc(size);

   for (i = 0; i < CYCLES; i++) {
       if (i < CYCLES / 2)
           j = i;
       else
           j--;

       size = sizeof(*p) * (j * 50 + 110);
       printf("realloc: %zu\n", size);
       p = realloc(p, size);

       size = sizeof(*p) * ((j + 1) * 150 + 110);
       printf("realloc: %zu\n", size);
       p = realloc(p, size);
   }

   free(p);
   exit(EXIT_SUCCESS);
}

Kompilacja programu C

$ gcc program.c

Test wykorzystania pamięcy z użyciem analizatora memusage

emusage ./a.out 
malloc: 400
realloc: 440
realloc: 1040
realloc: 640
realloc: 1640
realloc: 840
realloc: 2240
realloc: 1040
realloc: 2840
realloc: 1240
realloc: 3440
realloc: 1440
realloc: 4040
realloc: 1640
realloc: 4640
realloc: 1840
realloc: 5240
realloc: 2040
realloc: 5840
realloc: 2240
realloc: 6440
realloc: 2040
realloc: 5840
realloc: 1840
realloc: 5240
realloc: 1640
realloc: 4640
realloc: 1440
realloc: 4040
realloc: 1240
realloc: 3440
realloc: 1040
realloc: 2840
realloc: 840
realloc: 2240
realloc: 640
realloc: 1640
realloc: 440
realloc: 1040
realloc: 240
realloc: 440

Memory usage summary: heap total: 45464, heap peak: 7464, stack peak: 976
         total calls   total memory   failed calls
 malloc|          2           1424              0
realloc|         40          44040              0  (nomove:37, dec:19, free:0)
 calloc|          0              0              0
   free|          1            440
Histogram for block sizes:
  240-255             1   2% ============
  400-415             1   2% ============
  432-447             3   7% =====================================
  640-655             2   4% =========================
  832-847             2   4% =========================
 1024-1039            1   2% ============
 1040-1055            4   9% ==================================================
 1232-1247            2   4% =========================
 1440-1455            2   4% =========================
 1632-1647            4   9% ==================================================
 1840-1855            2   4% =========================
 2032-2047            2   4% =========================
 2240-2255            3   7% =====================================
 2832-2847            2   4% =========================
 3440-3455            2   4% =========================
 4032-4047            2   4% =========================
 4640-4655            2   4% =========================
 5232-5247            2   4% =========================
 5840-5855            2   4% =========================
 6432-6447            1   2% ============

Alternatywne narzędzia do analizy pamięci

Oprócz memusage istnieją inne narzędzia służące do monitorowania pamięci w systemie Linux:

  • top – ogólny monitor zasobów systemowych.
  • htop – ulepszona wersja top z bardziej intuicyjnym interfejsem.
  • ps – narzędzie do wyświetlania informacji o procesach.
  • valgrind – zaawansowane narzędzie do profilowania pamięci.
  • smem – szczegółowa analiza użycia pamięci RAM przez procesy.

Podsumowanie

Program memusage to potężne narzędzie dla programistów i administratorów Linux, które umożliwia monitorowanie i analizę zużycia pamięci przez aplikacje. Jego zastosowanie jest kluczowe w debugowaniu problemów związanych z pamięcią oraz optymalizacji kodu. Dzięki intuicyjnej obsłudze i czytelnym raportom użytkownicy mogą skutecznie zarządzać zasobami systemowymi i poprawiać wydajność swoich aplikacji.

Jeśli chcesz pogłębić wiedzę na temat analizy pamięci, warto zapoznać się także z innymi narzędziami, takimi jak valgrind, smem czy htop. Dobrze zorganizowane zarządzanie pamięcią jest kluczowe dla stabilności i efektywności systemów Linux.

TUX - maskotka systemu Linux

About the author

Autor "BIELI" to zapalony entuzjasta otwartego oprogramowania, który dzieli się swoją pasją na blogu poznajlinuxa.pl. Jego wpisy są skarbnicą wiedzy na temat Linuxa, programowania oraz najnowszych trendów w świecie technologii. Autor "BIELI" wierzy w siłę społeczności Open Source i zawsze stara się inspirować swoich czytelników do eksplorowania i eksperymentowania z kodem.