Topik wawancara representatif

Wawancara Linux: Bagaimana Cara Mendiagnosis OOM Kill?

UmumSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah node Linux 64 GiB masih memiliki MemAvailable sebesar 18 GiB, tetapi sebuah container dengan batas memori 4 GiB terus keluar dengan status OOMKilled dan exit code 137. Di cgroup v2, oom_kill meningkat di memory.events dan memory.current mendekati memory.max. Bagaimana Anda membuktikan pemicunya, membedakan cgroup OOM dari global OOM, menemukan sumber lonjakan memori, mengendalikan insiden dengan aman, dan mencegahnya terulang kembali?

Prompt dan Kapan Ini Berlaku

Sebuah node Linux 64 GiB masih memiliki 18 GiB MemAvailable, tetapi satu container berulang kali keluar selama enam jam. Runtime mencatat OOMKilled dan exit code 137. memory.max cgroup v2 milik workload tersebut adalah 4 GiB; sebelum kegagalan, memory.current mendekati batas tersebut dan oom_kill meningkat di memory.events. Selama periode yang sama, anon di memory.stat melonjak dari 1,2 GiB ke 3,5 GiB sementara file berada di sekitar 280 MiB. Jelaskan bagaimana Anda membuktikan pemicunya, membedakan cgroup OOM dari global OOM, melacak sumber lonjakan, menangani insiden secara aman, dan mencegah kejadian berulang.

Angka 64 GiB, 18 GiB, 4 GiB, rentang waktu enam jam, dan statistik penggunaan adalah asumsi wawancara, bukan tolok ukur kapasitas. Asumsikan Linux menggunakan cgroup v2 dan status runtime serta file cgroup merujuk pada rentang waktu kegagalan yang sama. Pertanyaan ini termasuk dalam general karena menguji reclaim sistem operasi, penghitungan cgroup, bukti OOM, dan penanganan proses; platform container hanya menyediakan skenario konteksnya.

Materi wawancara publik Linux dan sistem operasi yang diterbitkan pada tahun 2026 secara langsung menyertakan skenario OOM dan meminta kandidat untuk menganalisis log kernel, batas sumber daya, dan perilaku proses. Jawaban yang lengkap harus melampaui sekadar "tambahkan memori" atau "saya melihat 137": jawaban tersebut membutuhkan rantai bukti, penanganan yang aman, penelusuran sumber, dan pengujian yang dapat direproduksi yang menunjukkan bahwa perbaikan berfungsi.

Apa yang Dinilai oleh Pewawancara

Sinyal pertama adalah apakah kandidat menafsirkan bukti dengan benar. Berdasarkan konvensi exit-status Bash, 137 bisa berupa 128 ditambah sinyal 9, yang menunjukkan bahwa proses berakhir karena SIGKILL. Administrator, pengontrol batas waktu, atau OOM killer semuanya dapat mengirim sinyal tersebut. Alasan OOMKilled dari runtime, peningkatan memory.events:oom_kill pada rentang waktu yang sama, dan log kernel adalah hal-hal yang mengerucutkan penyebabnya ke OOM.

Sinyal kedua adalah apakah kandidat mengidentifikasi domain sumber daya. memory.max adalah batas tegas (hard limit) cgroup. Jika penggunaan mencapainya dan reclaim tidak dapat mengurangi beban tersebut, kernel dapat memicu OOM di dalam cgroup tersebut. Node bisa saja masih memiliki 18 GiB yang tersedia. Sebaliknya, OOM global muncul dari tekanan alokasi di seluruh node, dengan kelompok korban yang berbeda dan tindakan pemulihan yang berbeda.

Sinyal ketiga adalah kedisiplinan penghitungan memori. Hanya melihat RSS satu proses akan mengabaikan proses turunan (descendants), page cache, tmpfs, shared memory, socket buffer, dan data kernel yang dibebankan ke cgroup yang sama. Jawaban yang kuat merekonsiliasi memory.current, memory.peak, memory.stat, pengukuran per proses, dan profil aplikasi alih-alih menganggap VSZ, RSS, dan beban cgroup sebagai hal yang setara.

Terakhir, pewawancara menilai pertimbangan dalam penanganan insiden. Menaikkan limit untuk sementara waktu mungkin memulihkan layanan, atau bisa mengubah kebocoran yang sedang berlangsung menjadi kegagalan di seluruh node. Jawaban harus menjelaskan kapan harus membuang beban (shed load), me-restart, menskalakan, atau menaikkan limit; cara membedakan lonjakan normal dari kebocoran memori; serta bagaimana pengujian beban, soak test, dan kegagalan memvalidasi kebijakan tersebut.

Pertanyaan untuk Diklarifikasi Sebelum Menjawab

  • Apakah catatan tersebut merujuk pada instans container dan rentang kegagalan yang sama? Status OOMKilled lama, penghitung

cgroup saat ini, dan proses keluar yang berbeda tidak dapat membentuk rantai sebab-akibat. Selaraskan ID container, waktu mulai dan keluar, serta jalurnya.

  • Apakah host benar-benar menggunakan cgroup v2? v1 dan v2 menampilkan file dan semantik yang berbeda. Konfirmasikan apakah jalur tersebut

merupakan cgroup container atau parent yang berisi beberapa workload turunan.

  • Apakah oom_kill atau hanya oom yang berubah? oom menyatakan bahwa limit telah tercapai dan alokasi akan gagal;

oom_kill mencatat proses yang benar-benar dihentikan paksa oleh OOM killer. Periksa silang hitungan hierarki dengan memory.events.local.

  • Apakah node juga mengalami tekanan memori global? Periksa log kernel, MemAvailable, swap, PSI, event penggusuran (eviction),

dan beban kerja di sekitarnya. Cgroup OOM dan tekanan node dapat terjadi dalam waktu berdekatan.

  • Apakah limit 4 GiB milik container, Pod, atau cgroup parent? Batas parent dapat membatasi child

sebelum batas child itu sendiri tercapai. Telusuri hierarki dan periksa setiap batas efektifnya.

  • Workload apa yang berkorelasi dengan peningkatan memori? Konkurensi permintaan, kedalaman antrean, ukuran batch, kunci cache, koneksi,

ukuran input, dan versi deployment membantu membedakan working set yang menyusut kembali dari memori tertahan yang terus bertambah seiring waktu.

  • Berapa banyak proses yang berbagi cgroup? Sidecar, worker, dan proses child yang di-spawn semuanya berkontribusi pada beban penggunaan.

Hanya memprofilkan proses utama dapat melewatkan proses yang sebenarnya menjadi sumber pertumbuhan memori.

  • Apa saja persyaratan pemulihan dan integritas data? Menghentikan paksa satu anggota dari workload multiproses dapat meninggalkan

keadaan yang tidak konsisten. Restart, pembuangan beban, pengalihan lalu lintas, dan penghentian grup bergantung pada idempotensi dan RTO.

Kerangka Jawaban 30 Detik

“Saya akan memperlakukan 137 sebagai petunjuk SIGKILL, bukan kesimpulan pasti OOM. Saya akan menyelaraskan ID container dan waktu kegagalan, lalu memeriksa alasan OOMKilled runtime, memory.events.local cgroup target, memory.current, memory.max, dan log kernel. Node memiliki memori bebas, tetapi cgroup mencapai batasnya dan oom_kill meningkat, sehingga buktinya mengarah ke cgroup OOM. Saya akan mengurangi atau mengalihkan beban dan menyimpan bukti, menaikkan batas sementara hanya setelah memeriksa sisa kapasitas node. Kemudian saya akan membedah memori anonim, file, shared, dan kernel dengan memory.stat, serta mengkorelasikan profil per proses dengan metrik workload untuk membedakan antara kebocoran memori, cache tanpa batas, lonjakan konkurensi, atau batas ukuran yang terlalu kecil. Setelah perbaikan, saya akan menjalankan uji beban puncak representatif, soak test berdurasi panjang, dan uji batas terkontrol serta memasang peringatan pada memory.high, tekanan memori, beban puncak, dan event OOM.”

Pembahasan Mendalam Langkah demi Langkah

Langkah pertama: ubah terminasi menjadi satu linimasa.

Catat ID container, PID, waktu mulai dan keluar, versi yang di-deploy, jumlah restart, dan jalur cgroup. Exit 137 biasanya sesuai dengan SIGKILL dalam shell dan status container, tetapi ini tidak membuktikan adanya OOM: kill -9, batas waktu platform, atau agen node dapat menghasilkan hasil yang sama. Korelasikan reason: OOMKilled, delta dalam event cgroup, dan pesan kernel pada detik yang sama.

Utamakan memory.events.local agar penghitung hierarki parent tidak tercampur dengan event turunan. Jika oom_kill berubah dari 7 menjadi 8 pada penghentian ini, memory.current mendekati 4 GiB, dan log kernel melaporkan memory-cgroup OOM, itu adalah rantai bukti cgroup OOM yang koheren. Jika hanya ada 137, tanpa perubahan penghitung atau alasan OOM pada runtime, selidiki sinyal manual, batas waktu health-check, systemd-oomd, penggusuran (eviction), dan penghentian runtime sebagai gantinya.

Langkah kedua: identifikasi domain sumber daya OOM.

memory.max membatasi memori yang diperhitungkan untuk cgroup dan turunannya. Ketika batas tercapai dan direct reclaim tidak dapat memenuhi alokasi, kernel hanya dapat memilih korban dari cgroup tersebut. Oleh karena itu, 18 GiB MemAvailable pada host tidak melindungi container. Telusuri ke atas melalui cgroup parent untuk menemukan batas yang memory.max dan penghitung event-nya tercapai.

OOM Global memiliki bukti yang berbeda: memori node dan swap mendekati habis, PSI memori meningkat, log kernel mencakup status memori global beserta korbannya, dan workload lain ikut terpengaruh. Di bawah tekanan node, platform mungkin akan menggusur Pod terlebih dahulu. Remediasi cgroup OOM berfokus pada penggunaan workload dan batasnya; OOM global juga memerlukan koreksi pada overcommit node, request dan reservasi, daemon sistem, dan penempatan workload.

Langkah ketiga: jelaskan ke mana alokasi 4 GiB tersebut digunakan.

Mulailah dengan memory.current dan memory.peak, lalu uraikan pembebanannya dengan memory.stat. Di sini, anon melonjak dari 1,2 GiB ke 3,5 GiB selama enam jam sementara file berada di sekitar 280 MiB. Hal itu memprioritaskan heap, pemetaan anonim, dan proses yang memilikinya, tetapi belum membuktikan adanya kebocoran. Dokumentasi kernel menyatakan bahwa penghitungan cgroup juga mencakup page cache, tmpfs dan shared memory, struktur kernel, dan socket buffer; parent juga mencakup proses turunan.

Sandingkan total tersebut dengan RSS, PSS, pemetaan anonim, jumlah proses dan thread, metrik heap runtime, dan pengukuran bisnis dari setiap proses dalam satu linimasa. Jika objek aktif dan heap aplikasi tumbuh bersamaan, selidiki referensi yang tertahan atau cache tanpa batas. Jika heap stabil tetapi RSS tetap tinggi, periksa fragmentasi alokator, library native, atau mmap. Pertumbuhan pada file, shmem, sock, atau slab mengindikasikan file tmpfs, cache, antrean koneksi, atau objek kernel.

VSZ adalah ruang alamat virtual, bukan residensi fisik atau beban cgroup. Satu snapshot saja juga tidak cukup. Workload batch yang sehat dapat mencapai puncak dan turun kembali setelah reclaim; kebocoran memori umumnya menaikkan baseline selama siklus berulang pada beban yang sebanding. Bandingkan kemiringan grafik (slope) dan status stabil pasca-pelepasan pada throughput yang sama.

Langkah keempat: buat setiap hipotesis dapat diuji (falsifiable).

Buat daftar kandidat hipotesis yang ringkas dan nyatakan prediksi untuk masing-masing hipotesis. Pada lonjakan konkurensi, penggunaan memori harus mengikuti permintaan yang sedang berjalan dan menyusut saat permintaan selesai. Pada cache tanpa batas, jumlah entri dan anon naik bersamaan dan stabil saat kapasitas dibatasi. Pada antrean konsumen, kedalaman antrean, objek batch, dan memori bergerak bersamaan. Pada batas yang terlalu kecil, working set representatif yang stabil berulang kali mendekati batas tanpa kemiringan naik jangka panjang.

Gunakan heap profile, allocation profile, atau histogram objek yang sesuai untuk runtime tersebut, tetapi perhitungkan beban overhead pengumpulan datanya. Mulailah dengan metrik produksi berisiko rendah atau replika yang lalu lintasnya dialihkan; sebelum mengambil dump, verifikasi ruang disk, privasi, dan dampak jeda (pause cost). Ubah satu faktor pada satu waktu dalam perbandingan versi atau pemutaran ulang lalu lintas (traffic replay). Menaikkan batas, menonaktifkan cache, dan menurunkan konkurensi secara bersamaan akan mengaburkan akar penyebabnya.

Langkah kelima: pisahkan penanganan sementara dari perbaikan permanen.

Lindungi pengguna dan node terlebih dahulu: batasi konkurensi ke instans, jeda batch yang memakan banyak memori, alihkan lalu lintas, atau lakukan rollback ke versi yang diketahui aman. Jika pemutaran ulang aman dan status multiproses akan tetap konsisten, restart akan melepaskan memori dengan cepat. Jika mematikan satu worker merusak shared state, pertimbangkan untuk menghentikan workload sebagai satu kesatuan. Di cgroup v2, memory.oom.group=1 meminta OOM killer untuk memperlakukan cgroup sebagai satu kesatuan yang tidak dapat dipisahkan, tetapi semantik pemulihannya harus diuji.

Naikkan memory.max sementara hanya setelah mengukur sisa ruang node, perlindungan untuk workload di sekitarnya, dan perkiraan beban puncak. Sertakan masa berlaku, pemantauan, dan ambang batas rollback. Untuk pertumbuhan memori yang terus berlanjut, batas yang lebih besar hanya menunda OOM berikutnya. Perbaikan permanen dapat berupa membatasi cache, melepaskan referensi, membatasi ukuran batch dan konkurensi, memperbaiki siklus hidup proses child, atau mengubah ukuran request dan limit berdasarkan working set terukur dan toleransi lonjakan (burst allowance).

Jangan "menyelesaikan" insiden dengan menetapkan oom_score_adj=-1000 pada layanan normal. Hal itu mengecualikannya dari pemilihan OOM dan dapat memaksa kernel untuk mematikan proses yang lebih penting atau lebih banyak; simpan pengaturan tersebut hanya untuk tugas sistem penting setelah tinjauan kebijakan kegagalan secara menyeluruh. Swap juga mengubah perilaku reclaim dan latensi. Swap mungkin menyerap lonjakan singkat tetapi tidak memperbaiki pertumbuhan memori yang tak terbatas.

Langkah keenam: validasi kapasitas dan buat indikator peringatan dini.

Putar ulang lalu lintas representatif di bawah penghitungan dan limit cgroup yang setara dengan produksi. Uji beban stabil, beban puncak, input besar, pemulihan antrean, dan perilaku multiproses. Gunakan uji beban singkat untuk beban puncak, soak test yang lama untuk melihat slope pertumbuhan dan baseline pasca-pelepasan, serta batas bawah yang terkontrol untuk menguji peringatan, terminasi, restart, dan integritas data. Keberhasilan ditandai dengan tersedianya headroom pada target throughput dan latensi, memory.current yang menyusut, tidak ada oom_kill baru, dan tidak ada pemburukan pada tekanan node atau workload sekitar.

Gunakan memory.high sebagai batas kontrol sebelum hard limit: melampauinya akan men-throttle cgroup dan memicu direct reclaim tanpa langsung memanggil OOM, memberikan waktu untuk mengirim peringatan atau mengotomatiskan penanganan. Pantau rasio memory.current/memory.max, memory.peak, high, event max, oom, dan oom_kill, PSI memori, tingkat restart, heap aplikasi, dan slope pertumbuhan. Limit harus ditentukan dari pengukuran beban puncak dan soak test, serta ditinjau ulang ketika ada perubahan versi, konkurensi, atau distribusi input.

Contoh Jawaban Berkualitas Tinggi

“Pertama-tama saya akan membuktikan apakah OOM yang menyebabkan terminasi ini. Exit 137 menunjukkan proses menerima SIGKILL; penghentian manual dan timeout juga dapat menyebabkan hal tersebut. Saya akan menyelaraskan ID container, waktu keluar, dan jalur cgroup, lalu memeriksa alasan OOMKilled dari runtime, delta pada memory.events.local, dan log kernel. Jika oom_kill meningkat pada terminasi ini, memory.current menyentuh 4 GiB, dan log mengidentifikasi memory cgroup, maka hal tersebut mengonfirmasi terjadinya cgroup OOM.

Hal itu juga menjelaskan mengapa node masih memiliki 18 GiB yang tersedia. memory.max adalah batas tegas cgroup, dan kegagalan reclaim memaksa kernel memilih korban di dalam domain sumber daya tersebut tanpa menghabiskan memori host terlebih dahulu. Saya tetap akan memeriksa cgroup parent, PSI node, swap, dan log OOM global untuk mengesampingkan adanya tekanan node yang bersamaan atau penggusuran oleh platform.

Untuk penanganan insiden, saya akan membuang atau mengalihkan lalu lintas yang memakan banyak memori dan menyimpan metrik pra-kegagalan beserta profil ber-overhead rendah. Jika restart aman dilakukan, saya akan mengembalikan ke versi yang stabil. Saya hanya akan menaikkan batas sementara setelah memeriksa sisa kapasitas node dan workload sekitar, disertai batas waktu kedaluwarsa dan ketentuan rollback. Menambah memori bukanlah solusi permanen.

Untuk diagnosis, saya akan merekonsiliasi total cgroup menggunakan memory.current, memory.peak, dan memory.stat, lalu memeriksa RSS, PSS, pemetaan anonim, dan runtime heap per proses. Di sini anon melonjak dari 1,2 GiB ke 3,5 GiB sementara memori file berada di sekitar 280 MiB, jadi saya akan memprioritaskan heap, anonymous mmap, proses child, dan alokator, lalu membuktikan sumbernya dengan profil memori. Saya akan mengkorelasikan memori dengan konkurensi, panjang antrean, entri cache, ukuran batch, dan versi. Baseline yang naik pada beban yang sebanding mengindikasikan kebocoran memori; working set stabil yang menyusut kembali mengindikasikan lonjakan normal atau limit yang terlalu rendah.

Setelah perbaikan, saya akan menjalankan uji beban puncak dan soak test yang panjang di bawah batas cgroup yang sama, memverifikasi bahwa memori menyusut kembali, penghitung event berhenti bertambah, serta latensi dan throughput memenuhi target. Kemudian saya akan mengatur memory.high dan peringatan sebelum hard limit, memantau beban puncak, tekanan memori, event OOM, dan slope pertumbuhan, serta menentukan ukuran konkurensi, cache, dan kapasitas dari working set yang terukur. Untuk layanan multiproses, saya juga akan menguji integritas data setelah penghentian parsial sebelum memutuskan apakah OOM harus menghentikan seluruh grup.”

Kesalahan Umum

  • Menyimpulkan OOM hanya dari 137 → SIGKILL dapat berasal dari operator atau pengontrol timeout → **Korelasikan alasan

runtime, event cgroup, dan log kernel.**

  • Mengesampingkan OOM karena host memiliki memori bebas → Cgroup dapat mencapai batas tegasnya saat node masih memiliki kapasitas bebas →

Identifikasi domain sumber daya terlebih dahulu.

  • Hanya melihat RSS satu proses → Proses turunan, file, shared memory, dan beban kernel juga ikut dihitung → **Rekonsiliasi

total penggunaan dan bedah memory.stat.**

  • Menganggap VSZ sebagai penggunaan fisik → Ukuran address-space bukanlah penggunaan fisik aktual atau memori yang diperhitungkan → **Periksa silang RSS/PSS,

pemetaan memori, dan metrik cgroup.**

  • Menyebut setiap peningkatan anon sebagai kebocoran → Working set normal atau beban puncak batch juga dapat meningkat → **Bandingkan slope dan

baseline pasca-pelepasan pada beban yang setara.**

  • Langsung menggandakan batas memori → Tindakan ini dapat menunda kebocoran dan menghabiskan batas aman node → **Wajibkan bukti

kapasitas, masa berlaku, dan batas rollback.**

  • Membuat aplikasi kebal terhadap OOM → Dampak kerusakan dapat berpindah ke proses lain atau ke node itu sendiri → **Ubah oom_score_adj

hanya sebagai bagian dari kebijakan kegagalan menyeluruh.**

  • Hanya menjalankan uji beban selama satu menit → Uji coba singkat melewatkan kebocoran lambat dan fragmentasi → **Jalankan uji beban puncak

dan soak test berdurasi panjang.**

  • Hanya memasang peringatan pada batas maksimal (hard limit) → Bertindak saat mencapai memory.max biasanya sudah terlambat → **Gunakan memory.high, PSI, dan

slope pertumbuhan untuk tindakan lebih awal.**

  • Mengasumsikan pemulihan instan setelah satu worker mati → State bersama pada lingkungan multiproses mungkin menjadi tidak konsisten → **Uji terminasi

grup, restart, dan semantik pemulihan data.**

Pertanyaan Lanjutan dan Cara Menjawabnya

Pertanyaan Lanjutan 1: Exit code 137 muncul, tetapi oom_kill tidak meningkat. Apa yang Anda periksa selanjutnya?

Pertama, konfirmasikan jalur cgroup dan waktu event, serta baca memory.events.local agar Anda tidak membandingkan cgroup parent atau instans baru. Jika bukti OOM masih tidak ditemukan, periksa alasan terminasi runtime, timeout deployment atau health-check, audit trail operator, systemd-oomd, penggusuran (eviction) node, dan log kernel. Exit 137 hanya mengerucutkan hasil ke SIGKILL; hal ini tidak mengidentifikasi pengirimnya.

Pertanyaan Lanjutan 2: Bagaimana Anda membedakan kebocoran memori dari batas yang terlalu kecil?

Bandingkan siklus yang berulang pada throughput, input, dan konkurensi yang serupa. Kebocoran memori umumnya menaikkan baseline atau jumlah objek aktif dan tidak menyusut saat beban rendah. Batas yang terlalu kecil lebih cenderung gagal pada beban puncak yang dapat diulang dan kembali ke working set yang stabil setelahnya. Validasi dengan heap profile atau allocation profile, entri cache, proses child, ukuran batch, dan memory.stat; jangan hanya bergantung pada satu grafik. Kedua kondisi tersebut bisa saja terjadi bersamaan.

Pertanyaan Lanjutan 3: Kapan waktu yang tepat untuk menaikkan memory.max?

Naikkan batas tersebut ketika uji beban puncak representatif dan soak test menunjukkan perilaku normal yang working set kebutuhannya melebihi batas saat ini, sementara kapasitas node, reservasi, dan perlindungan beban sekitar masih menyisakan ruang yang aman. Peningkatan saat insiden memerlukan masa berlaku, pemantauan, dan ambang batas rollback. Jika penggunaan memori terus tumbuh tanpa batas, limit yang lebih tinggi hanyalah penanganan sementara; lakukan juga pembuangan beban dan perbaiki sumber lonjakan memori tersebut.

Pertanyaan Lanjutan 4: Bagaimana memory.high dan memory.max seharusnya bekerja bersama?

memory.high adalah batas pelambatan (throttling) dan direct reclaim; melewatinya tidak langsung memicu OOM killer, sehingga dapat memberikan ruang untuk observasi dan otomatisasi. memory.max adalah batas isolasi akhir dan dapat memicu cgroup OOM jika reclaim gagal. Tetapkan keduanya berdasarkan working set terukur, beban puncak, toleransi latensi, dan margin node, serta pasang peringatan secara terpisah pada event high, max, oom, dan oom_kill.

Pertanyaan Lanjutan 5: Mengapa layanan multiproses mungkin menggunakan memory.oom.group?

Jika mematikan satu worker meninggalkan shared state, lock, atau transaksi yang belum selesai dalam kondisi tidak konsisten, memperlakukan cgroup sebagai workload tunggal yang tidak dapat dipisahkan dapat membuat kegagalan dan pemulihan menjadi deterministik. Sebelum mengaktifkannya, uji waktu restart seluruh grup, idempotensi tugas, dan pemulihan data. Proses dengan oom_score_adj=-1000 merupakan pengecualian, jadi pastikan juga bahwa tidak ada bagian workload yang tertinggal.

Sumber publik

Pertanyaan terkait