Некоторое описание того, как работает ulimit
:
ulimit
имеет дело с системными вызовамиsetrlimit
и getrlimit
. Легко убедиться, чтоstrace
-процесс bash(ulimit
является компонентомbash
). Я установил 1024кб изmax memory size
:
$ ulimit -m 1024
В другой консоли:
$ strace -p
...
getrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
setrlimit(RLIMIT_RSS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
...
setrlimit
справочная страница написать следующее оRLIMIT_RSS
:
RLIMIT_RSS Specifies the limit (in pages) of the process's resident set (the number of virtual pages resident in RAM). This limit only has effect in Linux 2.4.x, x < 30, and there only affects calls to madvise(2) specifying MADV_WILLNEED.
madvice
Системный вызов — это просто совет ядру, и ядро может игнорировать этот совет. Даже справочная страница bash
о ulimit
пишет следующее:
-m The maximum resident set size (many systems do not honor this limit)
Вот почему -m
не работает.
Об опции -v
:
Выставил 1024 кб виртуальной памяти:
$ ulimit -v 1024
В другой консоли:
$ strace -p
...
getrlimit(RLIMIT_AS, {rlim_cur=RLIM64_INFINITY, rlim_max=RLIM64_INFINITY}) = 0
setrlimit(RLIMIT_AS, {rlim_cur=1024*1024, rlim_max=1024*1024}) = 0
...
setrlimit
справочная страница написать следующее оRLIMIT_AS
:
RLIMIT_AS The maximum size of the process's virtual memory (address space) in bytes. This limit affects calls to brk(2), mmap(2) and mremap(2), which fail with the error ENOMEM upon exceeding this limit. Also automatic stack expansion will fail (and generate a SIGSEGV that kills the process if no alternate stack has been made available via sigaltstack(2)). Since the value is a long, on machines with a 32-bit long either this limit is at most 2 GiB, or this resource is unlimited.
Программа состоит из 3 сегментов (данные, код, стек )составляют виртуальную память программы.
Сегмент кода является константой и содержит программные инструкции.
Сегмент данных управляется следующим:
Системный вызовbrk
регулирует размер сегмента данных(части виртуальной памяти )программы.
mmap
Системный вызов сопоставляет файл или устройство с виртуальной памятью процесса.
Многие программы выделяют память (прямо или косвенно )путем вызова стандартной функции из библиотеки C (malloc
), которая выделяет память из кучи(части сегмента данных ). malloc
настроить размер сегмента данных, вызвав системный вызов brk
.
Стек хранит переменные функций (переменная занимает память при выделении из стека ).
Вот почему вариант -v
вам подходит.
Если -v
достаточно для вашей задачи, то нет причин делать что-то еще и этого достаточно.
Если вы хотите взять под контроль огромное количество конкретных функций памяти для процесса (нехватки памяти, использования подкачки, лимита RSS, OOM и т. д. )я предлагаю вам использоватьпамять cgroupsвозможности.
Если ваше приложение является сервисом, предлагаю вам использоватьвозможности systemd slice , как наиболее удобные для контроля и ограничения ресурсов сервиса или группы сервисов (также его легко настроить вместо того, чтобы настраивать cgroups
напрямую ), которым управляет systemd
.
Ваша переменная PWD_HASH
содержит возврат каретки \r
в конце строки, которая перемещает последние два символа "}
в начало вывода.
Пример:
$ PWD_HASH='{SHA512-CRYPT}abcde'$'\r'
$ PWD_JSON=$(printf '{"password": "%s"}' "$PWD_HASH")
$ echo "$PWD_HASH"
{SHA512-CRYPT}abcde
$ echo "$PWD_JSON"
"}password": "{SHA512-CRYPT}abcde
$ echo "$PWD_JSON" | od -c
0000000 { " p a s s w o r d " : " { S
0000020 H A 5 1 2 - C R Y P T } a b c d
0000040 e \r " } \n
0000045