جواب کوتاه: اگر یک سرویس لینوکسی ناگهان با OOMKilled یا Out of Memory متوقف میشود، ابتدا Kernel Log را بررسی کنید و سپس RAM/Swap، مصرف Process، محدودیت cgroup و تنظیمات systemd را مقایسه کنید. بالا بردن RAM بدون پیدا کردن علت مصرف حافظه راهحل دائمی نیست.
تشخیص اولیه OOM
journalctl -k -b | grep -Ei 'oom|out of memory|killed process'
dmesg -T | grep -Ei 'oom|out of memory|killed process'RAM و Swap
free -h
swapon --show
cat /proc/meminfo | egrep 'MemAvailable|SwapTotal|SwapFree'Process پرمصرف
ps aux --sort=-%mem | head -20
ps -eo pid,ppid,user,%mem,rss,vsz,cmd --sort=-rss | head -20cgroup و systemd
systemctl show myservice -p ControlGroup -p MemoryCurrent -p MemoryMax -p OOMPolicyاگر MemoryMax محدود است، سرویس ممکن است داخل cgroup خودش OOM شود حتی وقتی Host هنوز حافظه دارد.
بررسی memory.events
CG=$(systemctl show -p ControlGroup --value myservice)
cat "/sys/fs/cgroup$CG/memory.events"
cat "/sys/fs/cgroup$CG/memory.current"
cat "/sys/fs/cgroup$CG/memory.max"افزایش oom_kill نشانه مهم OOM در همان cgroup است.
اصلاح Limit با احتیاط
systemctl show myservice -p MemoryMax -p MemoryHigh -p OOMPolicy
sudo systemctl edit myservice
[Service]
MemoryHigh=1500M
MemoryMax=2Gاعداد نمونهاند؛ Limit باید براساس مصرف واقعی و RAM Host تعیین شود.
Verify
systemctl status myservice --no-pager
systemctl show myservice -p MemoryCurrent -p MemoryMax
free -h
journalctl -k --since "-15 min" | grep -Ei 'oom|out of memory|killed process'Rollback
sudo systemctl revert myservice
sudo systemctl daemon-reload
sudo systemctl restart myserviceخطاهای رایج
- Restart بدون خواندن Kernel Log
- نادیده گرفتن cgroup و MemoryMax
- استفاده از Swap بهجای رفع memory leak
- تغییر افراطی oom_score_adj
برای مدیریت فشار حافظه، آموزش zram را ببینید. اگر OOM باعث Crash-loop سرویس شده است، راهنمای رفع خطای start request repeated too quickly در systemd نیز برای بررسی Restart و start-limit مفید است. برای شناخت دقیقتر کنترل سرویسها هم راهنمای systemd و مدیریت سرویسها و برای زیرساخت با منابع بیشتر سرور مجازی وانسرور را ببینید.