Вы так говорите, как будто лень не считается добродетелью в программировании :).
Большое количество программного обеспечения оптимизировано для простоты и удобства сопровождения, при этом выживание в условиях нехватки -памяти является очень низким приоритетом. Обычно сбой распределения рассматривается как фатальный. Выход из процесса, который исчерпывает память, позволяет избежать ситуации, когда свободной памяти нет, и система не может двигаться вперед без выделения дополнительной памяти или усложнения в виде всестороннего предварительного -выделения.
Обратите внимание, насколько велика разница между проверкой выделений и смертью или отсутствием проверки и сбоем. Было бы несправедливо винить в чрезмерной фиксации программистов, которые просто не удосужились проверить, удался ли malloc ()или нет.
Существует лишь небольшое количество программного обеспечения, которому можно доверять, чтобы оно продолжало «правильно» работать в условиях неудачных выделений. Как правило, следует ожидать, что ядро выживет. У sqlite есть общеизвестно надежный тест , который включает тестирование нехватки памяти, в частности потому, что он предназначен для поддержки различных небольших встраиваемых систем.
В качестве пути отказа, не используемого в нормальной работе, правильная обработка условий нехватки памяти налагает значительную дополнительную нагрузку на техническое обслуживание и тестирование. Если эти усилия не приносят соразмерной выгоды, их можно с большей пользой потратить в другом месте .
Там, где это не удается, также обычно используются специальные случаи для больших выделений, чтобы справиться с наиболее распространенными причинами сбоя.
Разрешениеопределенного количества чрезмерной фиксации , вероятно, лучше всего рассматривать в этом контексте.Это часть текущего компромисса по умолчанию в Linux.
Обратите внимание, что идея о том, что нужно отключить перегрузку на уровне ядра -и вместо этого предоставить больше подкачки , чем вы когда-либо хотели использовать, также имеет своих ненавистников. Разрыв в скорости между оперативной памятью и вращающимися жесткими дисками со временем увеличился, так что, когда система фактически использует пространство подкачки, которое вы ей разрешили, это чаще можно описать как «остановку».
Более компактное решение с использованием сценария оболочки:
nvidia-smi | grep ' C ' | while read _ _ pid _ _ mem; do
user="$( ps -o user "${pid}" | tail -n +2 )"
printf '%8s %6d %s\n' "${mem}" "${pid}" "${user}"
done
Обратите внимание, что это запускает три дополнительных процесса для каждого pid.
Оригинальное решение с использованиемawk
:
#! /bin/bash
function nvidia-smi { cat <<'[][]'
A C 937 D E 1.7MB
A C 1232 D E 0.25MB
A E 6112 D E 13MB
A C 2008 D E 437KB
A C 2024 D E 314157
[][]
}
AWK='
/ C / { Pid[NR] = $3; xPid[$3] = NR; Mem[NR] = $6; }
END {
for (j in Pid) pp = pp "," Pid[j];
cmd = "ps 2>&1 -o pid,user -p " substr (pp, 2);
while (cmd | getline)
if ($1 in xPid) User[xPid[$1]] = $2;
close (cmd);
fmt = "%8s %6d %s\n";
for (j = 1; j <= NR; ++j)
if (j in Mem)
printf (fmt, Mem[j], Pid[j], User[j]);
}
'
nvidia-smi | awk "${AWK}"
Функция nvidia -smi просто представляет некоторые тестовые данные --отбросить это. Вам нужна переменная AWK (12 строк в многострочной константе -между одиночными -кавычками )и кратким конвейером под ней.
Испытание. Я включил pid, который использовал память:
paul $./nVid
1.7MB 937 syslog
0.25MB 1232 root
437KB 2008 postfix
314157 2024 paul