SSD Nodes Learn 🎉 VPS mula $5.50/buwan
Mga Gabay Matt ConnorNi Matt Connor · Na-update 2026-08-13

Paano limitahan ang memory at CPU ng process sa systemd

Alamin kung bakit puwedeng mag-freeze ang VPS kahit may cap, at itakda ang MemoryHigh, MemoryMax, CPUQuota at TasksMax sa systemd unit.

Limitahan ang process memory at CPU gamit ang systemd drop-in

Nililimitahan mo ang process memory at CPU sa isang Linux VPS sa pamamagitan ng pagdaragdag ng ilang linya sa unit na nagpapatakbo sa process. Ang MemoryMax= ang hard ceiling sa memory. Ang CPUQuota= ang ceiling sa processor time. Pareho itong ipinapatupad ng cgroup v2 (control groups, version 2), ang kernel feature na ginagamit na ng systemd para itala ang paggamit ng bawat service sa server.

sudo systemctl edit myapp.service

Binubuksan nito ang isang drop-in file na may mga instruction sa comments. Idagdag ito sa itaas ng mga iyon:

[Service]
MemoryHigh=512M
MemoryMax=768M
MemorySwapMax=0
CPUQuota=80%
TasksMax=128
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
systemctl show myapp.service -p MemoryHigh -p MemoryMax -p CPUQuotaPerSecUSec -p TasksMax

Dapat ulitin ng systemctl show ang iyong mga numero gamit ang sariling units ng kernel: MemoryMax=805306368 at CPUQuotaPerSecUSec=800ms. Kung mag-print ito ng MemoryMax=infinity, hindi na-load ang drop-in. Suriin kung nailagay ang file sa /etc/systemd/system/myapp.service.d/override.conf at kung nagsisimula ito sa [Service] header, dahil kapag walang naunang section ang isang settings line, magla-log ang systemd ng Assignment outside of section. Ignoring. at sisimulan ang service nang walang anumang limit.

Ipinapaliwanag ng natitirang bahagi ng guide na ito kung paano piliin ang mga numerong iyon at kung ano pa ang maaaring magkamali matapos maitakda ang mga ito.

Bakit nag-freeze ang VPS dahil sa runaway process kahit hindi nito napupuno ang memory

Ang process na lumampas sa hard memory cap ay namamatay makalipas ang humigit-kumulang isang segundo at nire-restart ang service. Iyan ang magandang sitwasyon. Masama ang sitwasyon kapag walang namamatay: sumasagot ang box sa ping, tinatanggap ng SSH ang connection, pero hindi lumalabas ang shell prompt. Buhay at abala ang machine, pero walang silbi ang lahat ng ginagawa nito.

Narito ang mekanismo dahil hindi ito agad halata. Kapag kumokonti ang free memory, nagre-reclaim ang kernel ng pages sa halip na mamigay ng bago. Ang pinakamadaling i-reclaim ay ang file-backed pages, at nasa page cache ang executable code ng lahat ng tumatakbong process. Kaya ine-evict ng kernel ang text pages ng sshd, at ang susunod na instruction na tatakbo sa sshd ay isang page fault na kailangang basahin muli ang mga byte mula sa storage. Sa huli, naghihintay sa disk ang bawat process sa halip na tumakbo. Paulit-ulit na inaalis at ibinabalik ang parehong pages. Tinatawag itong thrashing.

Dalawang bagay ang nagpapalala nito sa VPS kumpara sa laptop. Madalas na network-attached o shared ang storage, kaya mas maraming milliseconds ang kailangan ng bawat fault kaysa sa local NVMe device. At hindi oras ang sinusukat ng kernel; failure ang sinusukat nito. Hangga't nakakapagbalik ang reclaim ng isang page, gaano man ito kabagal, naniniwala ang kernel na umuusad pa ito at hindi nito tinatawag ang out of memory (OOM) killer. Maaaring manatili ang box sa ganitong estado nang maraming minuto bago may mapatay.

Makikita mong nangyayari ito. Ini-export ng kernel ang pressure stall information (PSI) sa Linux 4.20 at mas bago:

cat /proc/pressure/memory
cat /proc/pressure/io
some avg10=63.72 avg60=41.02 avg300=12.33 total=13729481
full avg10=48.15 avg60=30.44 avg300=8.90 total=9114233

Ang full line ang mahalaga. Ibig sabihin ng full avg10=48.15, sa nakalipas na sampung segundo, 48% ng oras ay naka-stall ang lahat ng runnable task sa box habang naghihintay sa memory work, kaya walang tumatakbo. Sa healthy server, malapit sa zero ang value ng full. Kapag lampas 10, mabagal na itong maramdaman ng tao. Kapag 40 o higit pa, ito ang estadong inilalarawan ng mga tao bilang frozen.

Ito rin ang dahilan kung bakit hindi garantiya ang limitasyon kapag nag-iisa ito. Ang unit na nasa ilalim ng MemoryHigh= ay tine-throttle sa halip na patayin. Kaya nananatili itong buhay at mabagal, at walang nagre-restart dito dahil sa pananaw ng systemd ay hindi naman ito nag-fail. Ang capped unit na pinapayagan pa ring gumamit ng swap ay bumubuo ng reads at writes na sinisingil sa unit na iyon pero isinasagawa ng iisang shared device. Dahil dito, maaari nitong pataasin ang /proc/pressure/io para sa bawat ibang service sa box. Tinutukoy ng limits kung sino ang sasagot sa kakulangan, pero hindi nito nalilikha ang capacity.

Tiyaking gumagamit ng cgroup v2 ang iyong VPS

stat -fc %T /sys/fs/cgroup

cgroup2fs ang unified hierarchy na kailangan ng lahat ng setting sa ibaba. Ibig sabihin ng tmpfs na nag-boot ang server gamit ang mas lumang v1 layout, kung saan wala ang MemoryHigh= at MemorySwapMax= at iba ang OOM behavior sa bawat unit. Bilang default, gumagamit ng v2 ang Ubuntu 22.04 at mas bagong bersyon, pati ang Debian 11 at mas bagong bersyon. Hindi ito gumagamit ng v2 kapag lumang image ang gamit o nag-boot ang kernel gamit ang systemd.unified_cgroup_hierarchy=0.

Sa cgroup v2, awtomatikong ino-on ng systemd ang memory accounting para sa bawat unit. Kaya available na agad ang mga value:

systemd-cgtop -m

Inililista nito ang mga cgroup ayon sa memory use, kaya ito ang pinakamabilis na paraan upang malaman kung ano ang kumokonsumo ng resources ng server habang nakakasagot pa ito. Kung bago ang server, unahin ang account at firewall setup sa unang sampung minuto sa bagong VPS bago ito.

MemoryHigh nagta-throttle. MemoryMax pumapatay.

Ang pagkakaiba ng dalawang memory setting ang nagtatakda kung ano ang magiging anyo ng failure.

  • MemoryHigh= ay soft cap. Kapag lumampas dito, agresibong nagre-reclaim ang kernel mula sa cgroup na iyon at sadyang pinapabagal ang mga allocation nito. Maaari pa ring lumampas ang usage sa value, at walang pinapatay.
  • MemoryMax= ay hard cap. Kapag hindi matugunan ang allocation sa ilalim nito, tumatakbo ang OOM killer sa loob ng cgroup na iyon at pinapatay ang isa sa sariling process ng unit.

Ang ikalawang puntong ito ang tunay na dahilan kung bakit dapat magtakda ng MemoryMax= sa anumang hindi mo lubos na pinagkakatiwalaan. Kapag walang cap, problema ng buong server ang memory shortage, at pinipili ng global OOM killer ang victim batay sa oom_score, na kadalasan ay nangangahulugang pinakamalaking process. Karaniwan, ang pinakamalaking process ay ang database mo, hindi ang script na nag-leak. Kapag may cap, sa loob ng unit na sanhi ng problema napupunta ang pagpatay.

Itakda ang pareho, at ilagay ang MemoryHigh= nang humigit-kumulang 20 hanggang 30 porsiyento sa ibaba ng MemoryMax=. Warning zone ang pagitan: kapag mabagal ang leak, lalampas ito sa High at lalabas bilang serbisyong bumagal, samantalang ang biglaang spike ay dadaan agad sa Max at mamamatay.

Binabasa ang mga percentage value batay sa naka-install na physical memory, kaya ang MemoryMax=25% sa isang 4 GB plan ay 1 GB at mananatiling isang-kapat ng server kahit i-resize mo ang plan. Ganap na inilalayo ng MemorySwapMax=0 ang unit na iyon sa swap, kaya nagiging mabilis at malinaw na kill ang matagal na pagbagal.

Kailangang may restart policy kasabay ng cap, kung hindi, mag-iiwan lamang ang kill ng stopped service.

[Unit]
StartLimitIntervalSec=300
StartLimitBurst=5

[Service]
Restart=on-failure
RestartSec=5s

Ang StartLimit* ay dapat nasa [Unit], at ang Restart= ay nasa [Service]. Kapag nailagay ang alinman sa maling section, hindi ito papansinin ng systemd. Ang limang restart sa loob ng limang minuto ay leak na, hindi panandaliang aberya, kaya pagkatapos nito ay susuko ang systemd at iiwan ang unit na failed. Ito ang state na gusto mong makita sa susunod, sa halip na crash loop na nagtatago sa problema.

Limitahan ang CPU gamit ang CPUQuota, o magbahagi ng CPU gamit ang CPUWeight

Ang CPUQuota= ay kumokonsumo ng porsyento ng oras na available sa isang CPU. Ang CPUQuota=50% ay kalahati ng isang core. Ang CPUQuota=200% ay katumbas ng dalawang core, at maaaring ipamahagi ng unit sa kahit ilang thread na kailangan nito. Sa isang 2 vCPU plan, ang CPUQuota=200% ang buong machine.

Ang CPUWeight= ang mas mainam na default para sa karamihan ng service. Isa itong relative share mula 1 hanggang 10000, at 100 ang default ng kernel. Nakakaapekto lamang ito kapag may nag-uunahang workload: ang backup job na may CPUWeight=20 ay magbibigay-daan sa web server na may 100 kapag mataas ang load, at magagamit pa rin nito ang buong machine kapag idle ang machine. Sinasayang ng hard quota ang idle capacity na iyon.

Maging tumpak sa inaasahang pakinabang ng CPU limit. Karaniwang hindi pinapahinto ng CPU-bound process ang Linux, dahil patuloy na nagbibigay ang scheduler ng oras sa lahat ng process. Memory ang karaniwang nagpapabagsak sa machine. Gamitin ang CPUQuota= kapag kailangan mo ng predictable ceiling, halimbawa sa build o agent na kung wala nito ay tuloy-tuloy na gagamit ng buong CPU sa loob ng isang oras. Hiwa-hiwalay na usapin ang pag-size ng ganitong workload. Saklaw ito sa kung gaano karaming RAM at CPU ang kailangan ng coding agent VPS.

Kung mukhang busy ang CPU kahit kaunti lang ang ginagamit ng mga process mo, maaaring nasa kabilang panig ng hypervisor ang sanhi. Ito ang CPU steal time mula sa maingay na katabing tenant, at walang quota na itatakda mo ang makakapagbago rito.

TasksMax pumipigil sa fork loop

Ang TasksMax= ang bilang ng mga process at thread na maaaring hawakan ng isang unit. Kasama sa bilang ang mga thread, kaya mas malaking headroom ang kailangan ng Java o Go service kaysa sa ipinapakita ng process list. Ito ang pinakamurang proteksyon laban sa script na paulit-ulit na nagfa-fork, dahil nabibigo ang fork sa loob ng unit sa halip na maubusan ng process ID ang buong server.

TasksMax=128

Kapag naabot ng isang unit ang limit, nagla-log ang kernel ng linyang naglalaman ng pangalan ng cgroup:

cgroup: fork rejected by pids controller in /system.slice/myapp.service

Karaniwang nag-uulat ang mismong program ng fork: retry: Resource temporarily unavailable. Tingnan kung ano ang default na inilalapat ng manager gamit ang systemctl show -p DefaultTasksMax.

Limitahan ang isang one-off job gamit ang systemd-run

Hindi mo kailangan ng unit file para magamit ang alinman dito. Gumagawa ang systemd-run ng transient unit para sa isang command.

sudo systemd-run --scope -p MemoryMax=1G -p MemorySwapMax=0 -p CPUQuota=50% -p TasksMax=64 ./import-data.sh

Pinapatakbo ng --scope ang command sa iyong terminal matapos ipakita ang Running scope as unit: run-r7c1a....scope. Nananatili sa iyong screen ang output, at nawawala ang mga limit kapag natapos ang command. Gumagana ang anumang property mula sa systemd.resource-control pagkatapos ng -p.

Para sa matagal na job, alisin ang --scope at bigyan ito ng pangalan. Tatakbo ito sa background bilang transient service at magla-log sa journal:

sudo systemd-run --unit=nightly-import -p MemoryMax=1G -p CPUWeight=20 ./import-data.sh
journalctl -u nightly-import -f

Gumagana ang parehong mga option sa --user kapag hindi ka root, ngunit ang user manager mo ay mayroon lamang mga controller na ipinagkatiwala rito, kaya maaaring tanggihan doon ang isang property. Patakbuhin ito gamit ang sudo kapag nangyari iyon. Kapag kailangan na ng job ng permanenteng lugar, ilipat nang hindi binabago ang mga setting sa isang aktuwal na unit: tingnan ang pagpapatakbo ng script bilang systemd service at timer.

Ang tanong tungkol sa swap, sinagot nang tapat

Binabago ng swap ang anyo ng failure sa halip na pigilan ito.

Kapag walang swap, umaabot sa limit ang memory leak at may mamamatay sa loob ng ilang segundo. Malinaw at maikli ang outage, at madaling basahin sa journal pagkatapos. Kapag may swap, isinusulat ng kernel sa disk ang cold anonymous pages at nakakabili ito ng oras. Kung magse-stabilize sana ang proseso, maililigtas ka ng swap. Kung runaway ito, ginagawa ng swap na 20 minutong stall ang 5 segundong outage, at mas malala ang stall dahil kapag patay ang proseso, gumagana pa rin ang shell mo, samantalang kapag nagta-thrash ang system, hindi.

swapon --show
free -h

Isang praktikal na setup para sa maliit na VPS: gumamit ng katamtamang swap file para sa mga page na isang beses lang ina-allocate at hindi na muling ina-access, at itakda ang MemorySwapMax=0 sa mga unit na handa mong mawala. Mananatiling may swap ang mahahalagang serbisyo. Mabilis na tatama sa limit ang mga hindi mahuhulaang serbisyo at magre-restart.

Mahina ang epekto ng pagpapababa sa vm.swappiness, at mahalagang malaman kung bakit. Binabago lang nito ang balanse sa pagitan ng pag-evict ng page cache at pag-swap ng anonymous pages, at parehong mangangailangan ng disk read sa susunod. Binabago nito kung aling pages ang nagta-thrash, hindi kung magta-thrash ang system.

Pinapatay ng early OOM daemon ang proseso bago ang pagbagal

Hinihintay ng kernel na tuluyang mabigo ang reclaim. Sa maliit na VPS, ang paghihintay na ito ang eksaktong panahong nawawala sa iyo ang machine. Isinasara ito ng dalawang userspace daemon sa pamamagitan ng sarili nilang pag-monitor ng memory at mas maagang pagpatay sa proseso.

earlyoom ang nagmo-monitor ng available memory at free swap. Pinapatay nito ang prosesong may pinakamataas na score kapag bumaba sa threshold ang alinman sa mga ito.

sudo apt install earlyoom
systemctl status earlyoom

Awtomatikong sinisimulan ng Debian at Ubuntu package ang service kapag na-install. Nasa /etc/default/earlyoom ang mga option nito:

EARLYOOM_ARGS="-m 5,2 -s 5,2 --avoid '^(sshd|systemd)$' --prefer '^(node|python3)$'"

Itinatakda ng -m PERCENT ang minimum na available memory, at ng -s PERCENT ang minimum na free swap. Parehong 10 percent ang default. Ang pangalawang numero sa bawat pares ang SIGKILL point. Nagpapadala ang earlyoom ng SIGTERM kapag bumaba ka sa unang value, at SIGKILL naman kapag bumaba sa pangalawa. Bilang default, kalahati ito ng unang value. Ilapat ang pagbabago gamit ang sudo systemctl restart earlyoom. Basahin ang journalctl -u earlyoom upang makita kung aling proseso ang pinatay nito at kung gaano karaming memory ang hawak ng prosesong iyon.

systemd-oomd ang isa pang option. Inilalarawan ito ng manual page nito bilang “isang system service na gumagamit ng cgroups-v2 at pressure stall information (PSI) upang mag-monitor at magsagawa ng corrective action bago magkaroon ng OOM sa kernel space.” Kumakilos ito sa buong cgroup sa halip na sa indibidwal na proseso. Kaya unit ang pinapatay nito, hindi isang hiwalay na child process. Nag-o-opt in ang mga unit gamit ang ManagedOOMMemoryPressure=kill o ManagedOOMSwap=kill. Nasa /etc/systemd/oomd.conf ang mga threshold.

systemctl status systemd-oomd
oomctl

Ipinapakita ng oomctl kung ano ang kasalukuyang mino-monitor nito. Madalas ay wala itong mino-monitor sa server image dahil opt-in ang setting para sa bawat unit. Pumili ng isang daemon at iyon lamang ang gamitin. Kapag parehong tumatakbo, dalawang proseso ang nag-uunahang pumili ng victim. Dahil dito, mas mahirap tukuyin ang dahilan ng bawat pagpatay.

Aling unit ang responsable?

Magsimula sa kernel, dahil itinatala nito ang bawat prosesong pinapatay nito.

journalctl -k --grep "Killed process" --since "2 hours ago"

Ganito ang hitsura ng kill mula sa global OOM killer:

Out of memory: Killed process 4127 (node) total-vm:2731084kB, anon-rss:1874232kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:4212kB oom_score_adj:0

Ang anon-rss ay ang memory na hawak ng prosesong iyon sa RAM nang mamatay ito, mga 1.8 GB dito. Basahin nang may pag-iingat ang pangalan sa loob ng mga bracket. Iyon ang prosesong pinili ng kernel bilang biktima. Pinipili ng kernel ang pinakamalaking proseso, na hindi palaging siyang naging sanhi ng kakulangan.

Iba ang prefix ng kill mula sa cgroup limit. Nakasulat sa report sa itaas nito ang cgroup na umabot sa sarili nitong limit:

Memory cgroup out of memory: Killed process 8811 (python3) total-vm:1044320kB, anon-rss:769112kB, file-rss:0kB, shmem-rss:0kB, UID:998 pgtables:1720kB oom_score_adj:0

Karamihan ng diagnosis ay nasa prefix na iyon. Ibig sabihin ng Memory cgroup out of memory, may isang unit na umabot sa itinakda mong MemoryMax= at maayos ang natitirang bahagi ng server. Kapag simpleng Out of memory ang nakalagay, naubusan ng memory ang buong machine. Maaaring walang caps ang iyong mga unit, o masyadong mataas ang mga ito kapag pinagsama.

Pagkatapos, itanong sa systemd kung ano ang nakita nito:

systemctl status myapp.service
journalctl -u myapp.service -n 50
myapp.service: A process of this unit has been killed by the OOM killer.
myapp.service: Main process exited, code=killed, status=9/KILL
myapp.service: Failed with result 'oom-kill'.

Sinasabi ng systemctl status ang parehong bagay sa isang linya, bilang Active: failed (Result: oom-kill).

Ang cgroup counters ang ikatlong source. Ito lamang ang nagtatala ng throttling, na hindi kailanman gumagawa ng log line:

cat /sys/fs/cgroup/system.slice/myapp.service/memory.events
cat /sys/fs/cgroup/system.slice/myapp.service/memory.peak
low 0
high 4213
max 118
oom 12
oom_kill 12

Binibilang ng high kung ilang beses lumampas ang unit sa MemoryHigh= at na-throttle. Binibilang ng max kung gaano kadalas nitong naabot ang hard cap. Binibilang naman ng oom_kill ang aktuwal na pinatay na mga proseso. Ang malaking high na may oom_kill 0 ay ang tahimik na sitwasyong nabanggit kanina: tumatakbo ang service, napakabagal nito, at wala itong naiulat na failure. Naglalaman ang memory.peak (Linux 5.19 at mas bago) ng pinakamataas na usage na naabot ng cgroup. Iyan ang numerong gagamitin sa pag-size ng MemoryMax=. Nire-reset ang dalawang file kapag nag-restart ang unit, dahil nililikha muli ng systemd ang cgroup.

May isang prerequisite na pinagbabatayan ng lahat ng ito. Kung wala ang /var/log/journal, nasa RAM ang journal. Mawawala ang bawat linya pagkatapos ng reboot na kailangan mong gawin para ma-recover ang server.

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots

Kapag nagpapakita ang journalctl --list-boots ng higit pa sa kasalukuyang boot, nakaligtas na sa reboot ang history. Dahil dito, maipapakita sa iyo ng journalctl -k -b -1 ang mga kernel message mula sa boot na nag-fail.

Panimulang setting para sa isang maliit na VPS

Sa isang 2 GB plan, maglaan ng 300 hanggang 400 MB para sa kernel at page cache. Huwag hayaang umabot sa buong 2 GB ang pinagsamang caps, dahil maaaring mag-peak nang sabay-sabay ang bawat unit. Ibigay ang pinakamalaking bahagi sa pinakamahalagang service. Pagkatapos, lagyan ng cap ang lahat ng speculative service sa paligid nito.

[Service]
MemoryHigh=256M
MemoryMax=384M
MemorySwapMax=0
CPUWeight=20
TasksMax=64
Restart=on-failure
RestartSec=5s

Mahalagang may natitira kang paraan para makapasok sa system. Sa pamamagitan ng OOMScoreAdjust=-500 sa isang drop-in para sa ssh.service, mas maliit ang posibilidad na piliin ng global OOM killer ang SSH daemon bilang biktima nito. Ito ang maaaring magtakda kung maaayos mo ang server o kailangan mo itong i-reboot mula sa control panel. Binabago lamang nito ang pagpili ng kernel sa biktima. Hindi nito pinaiikli ang stall.

Tumatakbo ang mga container sa sarili nilang cgroup. Ang container runtime ang gumagawa ng mga ito, hindi ang iyong unit files. Kaya ang limit sa docker.service ay hindi nagiging limit para sa isang container. Ang mga katumbas na per-container ng MemoryMax= at CPUQuota= ay nasa pagtatakda ng memory at CPU limits sa Docker Compose.

FAQ

Bakit nag-freeze ang VPS ko sa halip na patayin ang runaway process?

Dahil sinusukat ng kernel ang pag-usad batay sa kung nakapagbalik ng pages ang reclaim, hindi sa tagal ng prosesong iyon. Kapag kapos ang memory, ine-evict nito ang page cache, pati ang executable pages ng mga tumatakbong program, at binabasa muli ang mga ito sa susunod na instruction. Naghihintay ang lahat sa storage at wala pang allocation na teknikal na nabigo, kaya hindi kailanman tinatawag ang OOM killer. Suriin ang /proc/pressure/memory habang nangyayari ito: kapag higit sa 40 ang full avg10, halos walang task ang nakatakbo sa nakaraang sampung segundo. Ang userspace daemon gaya ng earlyoom ay pumapatay ng process bago umabot ang system sa ganitong estado.

Ano ang pagkakaiba ng MemoryHigh at MemoryMax?

Ang MemoryHigh= ay soft cap na nagti-throttle. Mas agresibong nagre-reclaim ang kernel mula sa unit at pinapabagal ang allocations nito, pero maaaring lumampas ang usage sa value at walang pinapatay. Ang MemoryMax= ay hard cap: kapag hindi matugunan sa ilalim nito ang isang allocation, tinatawag ang OOM killer sa loob ng sariling cgroup ng unit, kaya ang process na naging sanhi ng problema ang namamatay sa halip na ang pinakamalaking process sa machine. Itakda ang MemoryHigh= na mas mababa sa MemoryMax= at ituring na warning zone ang pagitan ng mga ito.

Paano ko malalaman kung aling service ang tinamaan ng OOM killer?

Patakbuhin ang journalctl -k --grep "Killed process" --since "2 hours ago". Ang linyang nagsisimula sa Memory cgroup out of memory ay nangangahulugang may unit na lumampas sa sarili nitong MemoryMax=, habang ang simpleng Out of memory ay nangangahulugang naubusan ng memory ang buong machine. Pagkatapos, patakbuhin ang journalctl -u <unit> -n 50 at hanapin ang Failed with result 'oom-kill'. Kung wala ang /var/log/journal sa server mo, nasa RAM ang journal at nawala ang ebidensya nang mag-reboot, kaya gawin ang directory na iyon bago ang susunod na insidente.

Dapat ba akong magdagdag ng swap sa maliit na VPS?

Nakakatulong ang maliit na swap file para sa cold pages na isang beses lang ina-allocate at hindi na muling ginagamit. Hindi ito nakakatulong sa runaway process: ipinagpapaliban lamang nito ang pagpatay at pinapalitan ang maikling outage ng matagal na stall na hindi mo maa-access para maayos. Panatilihing katamtaman ang swap, at itakda ang MemorySwapMax=0 sa mga unit na maaari mong mawala, upang maabot ng mga ito ang ceiling at mabilis na mag-restart habang nananatili ang swap ng mahahalagang service.

Maaari ko bang limitahan ang isang command nang hindi gumagawa ng unit file?

Oo. Pinapatakbo ng sudo systemd-run --scope -p MemoryMax=1G -p CPUQuota=50% ./script.sh ang command sa terminal mo sa loob ng transient scope na may mga limitasyong iyon, at nawawala ang mga limitasyon kapag natapos ito. Available ang bawat property mula sa systemd.resource-control pagkatapos ng -p, kaya gumagana rin doon ang MemorySwapMax=, TasksMax= at CPUWeight=. Alisin ang --scope at idagdag ang --unit=name upang patakbuhin ang job sa background habang ang output nito ay napupunta sa journal.