Разбираемся, почему MemFree почти всегда близок к нулю, и как правильно читать /proc/meminfo. Практический пример на Python для мониторинга.
Если вы когда-нибудь смотрели на /proc/meminfo и видели значение MemFree всего в несколько сотен мегабайт при 16 ГБ ОЗУ, вас, вероятно, охватила паника. Но не спешите бежать за новым модулем памяти. На самом деле, Linux устроен так, что свободная память — это расточительство. Ядро предпочитает использовать каждый невостребованный байт для кэширования файлов и буферизации записи, а при необходимости мгновенно возвращает эту память процессам. Поэтому MemFree на здоровой системе стремится к нулю. Настоящий показатель, на который стоит ориентироваться — MemAvailable. В этой статье мы разберём, как правильно читать /proc/meminfo, избежать типичных ошибок и написать простой мониторинг памяти на Python.
Файл /proc/meminfo содержит ключевые метрики памяти. Вот типичный вывод:
MemTotal: 14177796 kB
MemFree: 497404 kB
MemAvailable: 7490900 kB
Buffers: 1235656 kB
Cached: 5146132 kB
SwapCached: 81068 kB
Обратите внимание на SwapCached — это ловушка. Если вы парсите строки по подстроке Cached, то SwapCached перезапишет значение Cached, и вы получите неверные данные. Решение: разбивать строку по двоеточию и сравнивать метку строго.
Напишем скрипт, который корректно читает /proc/meminfo и вычисляет использованную память по формуле Used = Total - Available.
def parse_meminfo():
"""Парсит /proc/meminfo и возвращает словарь с ключевыми метриками."""
mem = {}
with open('/proc/meminfo', 'r') as f:
for line in f:
parts = line.split(':')
if len(parts) != 2:
continue
label = parts[0].strip()
value_str = parts[1].strip().split()[0] # убираем 'kB'
try:
value_kb = int(value_str)
except ValueError:
continue
# Точное сопоставление меток
if label == 'MemTotal':
mem['total'] = value_kb
elif label == 'MemAvailable':
mem['available'] = value_kb
elif label == 'MemFree':
mem['free'] = value_kb
elif label == 'Cached': # не SwapCached!
mem['cached'] = value_kb
return mem
meminfo = parse_meminfo()
if 'total' in meminfo and 'available' in meminfo:
used = meminfo['total'] - meminfo['available']
print(f"Использовано: {used} kB")
else:
print("Не удалось получить все метрики")
Обратите внимание: значения в /proc/meminfo указаны в кибибайтах (kB = 1024 байта), поэтому при переводе в гигабайты используйте деление на 1024, а не на 1000.
При выводе значений памяти удобно использовать три значащие цифры — так столбцы остаются ровными. Например, 13.5 GiB, 6.42 GiB, 271 MiB. Реализуем функцию форматирования:
def format_bytes(value_kb):
"""Форматирует значение в kB в человекочитаемый вид с тремя значащими цифрами."""
units = ['KiB', 'MiB', 'GiB', 'TiB']
unit_idx = 0
value = float(value_kb)
while value >= 1024.0 and unit_idx < len(units) - 1:
value /= 1024.0
unit_idx += 1
# Определяем количество десятичных знаков
if value >= 100.0:
decimals = 0
elif value >= 10.0:
decimals = 1
else:
decimals = 2
return f"{value:.{decimals}f} {units[unit_idx]}"
print(format_bytes(14177796)) # 13.5 GiB
print(format_bytes(497404)) # 485.7 MiB
Теперь вы знаете, что MemFree — это не показатель нехватки памяти. Используйте MemAvailable для оценки реального объёма доступной памяти. Напишите скрипт на Python, который каждые 10 секунд выводит использованную и доступную память, и вы всегда будете в курсе состояния системы. Не дайте себя обмануть старым мифам — Linux эффективно использует каждый байт!
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →