Рубрики
Uncategorized

Потребление памяти в Linux

В мире DevOps существует множество инструментов, которые поддерживают нас для мониторинга использования памяти с помощью метрик, таких как Dat Dat … с меткой Linux, DevOps, Cloudopz, мониторинг.

В мире DevOps есть много инструментов, поддерживающих нас, чтобы отслеживать использование памяти с помощью метрик, таких как DataDogs, Grafana и т. Д. Но традиционные люди все еще просят знания и навыки мониторинга потребления памяти вручную.

  • В этой статье объясняется разумный метод измерения потребления памяти процесса на Linux. Linux оснащен управлением виртуальной памятью, и, следовательно, измерение потребления памяти одного процесса не так просто, как думают большинство пользователей. В этой статье объясняется, какую информацию вы можете получить от каждого показателя, связанного с потреблением памяти.

  • Инструменты Linux чаще всего используются VSZ (размер виртуальной памяти) и RSS (размер набора жителей) и новый — PSS (пропорциональный размер набора)

Что в этом документе

  • Технические понятия
  • VSZ (размер виртуальной памяти) и спрос Пейджинг
  • RSS (размер набора жителей) и общие библиотеки
  • PSS (пропорциональный размер набора)
  • Скрипт Python для получения PSS (пропорциональный размер набора)

🚀 Технические термины

1. страница

  • Это блок памяти, который используется в управлении памятью на Linux. Одна страница составляет 4096 байтов в типичных системах Linux.

2. физическая память

  • Это фактическая память, как правило, оперативная память, то есть на компьютере.

3. виртуальная память

  • Это пространство памяти, предоставляемое процессу, который позволяет процессу думать, что у него есть своя непрерывная память, которая изолирована от других процессов независимо от фактической суммы памяти на компьютере или ситуации с использованием памяти других процессов. Страница виртуальной памяти может быть сопоставлена со страницей физической памяти, и, следовательно, процессы должны только думать о виртуальной памяти.

🚀 VSZ (размер виртуальной памяти) и спрос Пейджинг

  • Учитывая VSZ (размер виртуальной памяти) для измерения потребления памяти процесса, не имеет большого смысла. Это связано с функцией, называемой Paging Paging, которая подавляет ненужное потребление памяти.

  • Например, текстовый редактор с именем EMACS имеет функции, которые могут обрабатывать файлы XML. Эти функции, однако, не используются все время. Загрузка этих функций в физическую память не требуется, когда пользователь просто хочет отредактировать простой текст. Функция подтяжки спроса не загружает страницы, если они не используются в процессе.

  • Вот как это работает. Во -первых, когда программа запускается, Linux дает пространство виртуальной памяти процессу, но на самом деле не загружает страницы, которые имеют функции в физическую память. Когда программа фактически вызывает функцию в виртуальной памяти, MMU в процессоре говорит Linux, что страница не загружена. Затем Linux приостанавливает процесс, загружает страницу в физическую память, отображает страницу в виртуальную память процесса, а затем позволяет процессу снова работать с того места, где он был приостановлен. Таким образом, процесс не должен знать, что он был приостановлен, и просто предположим, что функция была загружена на виртуальную память и использует ее.

  • VSZ (размер виртуальной памяти) описывает весь размер виртуальной памяти процесса независимо от страниц, загружаемых на фактическую память или нет. Следовательно, это не реалистичный показатель для измерения потребления памяти, поскольку оно включает страницы, которые фактически не потребляются.

🚀 RSS (размер набора жителей) и общие библиотеки

  • RSS (размер набора резидентов) описывает общее количество страниц для процесса, который фактически загружается в физическую память. Это может звучать как реальное количество памяти, потребляемой процессом, и лучше, чем VSZ (размер виртуальной памяти), но это не так просто из -за функции, называемой общими библиотеками или динамическими библиотеками связывания.

  • Библиотека — это модуль, который может использоваться программами для обработки определенной функции. Например, libpng.so заботится о сжатии и декомпрессии файлов изображений PNG, и Libxml2.so заботится об обработке файлов XML. Вместо того, чтобы заставлять каждого программиста писать эти функции, они могут использовать библиотеки, разработанные другими, и достигать желаемого результата.

  • Общий объект — это библиотека, которая может быть передана несколькими программами или процессами. Например, допустим, есть два процесса, работающие одновременно, которые хотят использовать функции обработки XML, которые находятся в общей библиотеке Libxml2.so. Вместо того, чтобы загружать страницы, которые имеют одни и те же функции несколько раз, Linux загружает их один раз в физическую память и отображает ее в виртуальную память оба процесса. Оба процесса не должны заботиться, делятся ли они функциями с кем -то другим, потому что они могут получить доступ к функциям и использовать их в своей собственной виртуальной памяти. Из -за этой функции Linux подавляет ненужное дублирование страниц памяти.

  • Теперь давайте вернемся к тому же примеру выше. EMACS, текстовый редактор, имеет функции, которые могут обрабатывать XML -файлы. Об этом позаботится общей библиотекой libxml2.so. На этот раз пользователь, который запускает EMACS, на самом деле работает с XML -файлами, и EMACS использует функции в LibxML2.so. Между тем, в фоновом фоновом режиме есть еще два процесса, которые также используют libxml2.so. Поскольку libxml2.so является общей библиотекой, Linux загружает ее только один раз в физическую память и отображает ее во всех трех процессах виртуальной памяти.

  • Когда вы увидите RSS (размер набора резидентов) EMACS, он будет включать страницы LibxML2.so. Это не неправильно, потому что Emacs на самом деле использует его. Но как насчет двух других процессов? Это не просто EMACS, который использует эти функции. Если вы суммируете RSS (размер набора резидентов) всех трех процессов, Libxml2.so будет подсчитываться три раза, даже если он загружается только один раз в физическую память.

  • Следовательно, RSS (размер набора резидентов) является индикатором, который будет показывать потребление памяти, когда процесс работает самостоятельно, не разделяя ничего с другими процессами. В практических ситуациях, когда библиотеки разделяются, RSS (размер набора резидентов) будет переоценить количество памяти, потребляемой процессом. Использование для измерения потребления памяти процесса не ошибочно, но вы можете помнить об этом поведении.

🚀 PSS (пропорциональный размер набора)

  • PSS (пропорциональный размер набора) является относительно новым индикатором, который можно использовать для измерения потребления памяти одного процесса. Это еще не доступно во всех системах Linux, но если он доступен, это может пригодиться. Концепция состоит в том, чтобы равномерно разделить сумму памяти общих страниц между процессами, которые их используют.

  • Вот как PSS (пропорциональный размер набора) рассчитывает потребление памяти: если есть n процессов, которые используют общую библиотеку, каждый процесс потребляет один n-й-й страницы общих библиотек.

  • Для примера выше, Emacs и два других процесса делились страницами Libxml2.so. Поскольку существует три процесса, PSS рассмотрит, что каждый процесс потребляет одну треть страниц libxml2.so.

  • Я рассматриваю PSS (пропорциональный размер набора) как более реалистичный показатель по сравнению с RSS (размер набора резидентов). Это хорошо работает, особенно если вы хотите рассмотреть потребление памяти всей системы вместе, а не каждый процесс индивидуально. Например, когда вы разрабатываете систему, которая имеет несколько процессов и демонов, и вы хотите оценить, сколько памяти вы должны установить на устройство, PSS (пропорциональный размер набора) работает лучше, чем RSS (размер набора резидентов).

🚀 Сценарий Python, чтобы получить PSS (пропорциональный размер набора

https://github.com/vumdao/pss-memory-get/blob/master/pss.py

#! /usr/bin/env python3
# coding: utf-8
##-----------------------------------------------------------------------------
## pss.py --- Print the PSS (Proportional Set Size) of accessable processes
##-----------------------------------------------------------------------------
import os, sys, re, pwd
from functools import cmp_to_key as cmp


##-----------------------------------------------------------------------------
def pss_main():
    '''
    Print the user name, pid, pss, and the command line for all accessable
    processes in pss descending order.
    '''
    # Get the user name, pid, pss, and the command line information for all
    # processes that are accessable. Ignore processes where the permission is
    # denied.
    ls = []   # [(user, pid, pss, cmd)]
    for pid in filter(lambda x: x.isdigit(), os.listdir('/proc')):
        try:
            ls.append((owner_of_process(pid), pid, pss_of_process(pid), cmdline_of_process(pid)))
        except IOError:
            pass

    # Calculate the max length of the user name, pid, and pss in order to
    # print them in aligned columns.
    userlen = 0
    pidlen = 0
    psslen = 0
    for (user, pid, pss, cmd) in ls:
        userlen = max(userlen, len(user))
        pidlen = max(pidlen, len(pid))
        psslen = max(psslen, len(str(pss)))

    # Get the width of the terminal.
    with os.popen('tput cols') as fp:
        term_width = int(fp.read().strip())

    # Print the information. Ignore kernel modules since they allocate memory
    # from the kernel land, not the user land, and PSS is the memory
    # consumption of processes in user land.
    fmt = '%%-%ds  %%%ds  %%%ds  %%s' % (userlen, pidlen, psslen)
    print(fmt % ('USER', 'PID', 'PSS', 'COMMAND'))
    for (user, pid, pss, cmd) in sorted(ls, key=cmp(lambda x, y: (y[2] - x[2]))):
        if cmd != '':
            print((fmt % (user, pid, pss, cmd))[:term_width - 1])


##-----------------------------------------------------------------------------
def pss_of_process(pid):
    '''
    Return the PSS of the process specified by pid in KiB (1024 bytes unit)

    @param pid  process ID
    @return     PSS value
    '''
    with open('/proc/%s/smaps' % pid) as fp:
        return sum([int(x) for x in re.findall('^Pss:\s+(\d+)', fp.read(), re.M)])


##-----------------------------------------------------------------------------
def cmdline_of_process(pid):
    '''
    Return the command line of the process specified by pid.

    @param pid  process ID
    @return     command line
    '''
    with open('/proc/%s/cmdline' % pid) as fp:
        return fp.read().replace('\0', ' ').strip()


##-----------------------------------------------------------------------------
def owner_of_process(pid):
    '''
    Return the owner of the process specified by pid.

    @param pid  process ID
    @return     owner
    '''
    try:
        owner_pid = pwd.getpwuid(os.stat('/proc/%s' % pid).st_uid).pw_name
    except Exception:
        return 'docker'
    return owner_pid


##-----------------------------------------------------------------------------
if __name__ == '__main__':
    pss_main()
  • Как бежать Sudo Python pss.py

  • Если запуск сервера/экземпляра Docker Тогда это покажет пользователь иуд 999 рефери

Рефс

🌠 Блог · GitHub · Web · LinkedIn · Группа · Страница · Twitter 🌠

Оригинал: «https://dev.to/vumdao/memory-consumption-in-linux-3b55»