Ubuntu cepat kehabisan RAM, dan komputer saya mulai membeku. Perintah apa yang akan menyelesaikan ini?

73

Ini sering terjadi pada saya ketika saya sedang mengkompilasi perangkat lunak di latar belakang dan tiba-tiba semuanya mulai melambat dan akhirnya membeku [jika saya tidak melakukan apa-apa], karena saya kehabisan RAM dan ruang swap.

Pertanyaan ini mengasumsikan bahwa saya memiliki cukup waktu dan sumber daya untuk membuka Terminal Gnome, mencari melalui sejarah saya, dan menjalankan satu sudoperintah.

Perintah apa yang bisa menyelamatkan saya dari keharusan melakukan boot ulang keras, atau boot ulang sama sekali?

Akiva
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Thomas Ward
1
Jika Anda kehabisan ruang swap, saya pikir Anda memiliki terlalu sedikit. Saya mendapat 20G ruang swap di komputer ini. Intinya adalah untuk memberi Anda cukup waktu dengan sistem yang dapat digunakan untuk membunuh apa pun yang memakan memori Anda. Ini bukan sesuatu di mana Anda hanya mengambil apa yang akan Anda gunakan, tetapi apa yang Anda harap tidak akan pernah Anda gunakan.
JoL
1
Apakah Anda yakin RAM dan swap sedang diisi? Jika itu yang terjadi, penangan OOM akan membunuh kompiler Anda dan membebaskan memori (dan juga mengacaukan proses pembuatan Anda). Kalau tidak, saya pikir itu baru saja diisi, dan mungkin sistem Anda lambat karena swap Anda ada di disk sistem Anda.
sudo
3
Coba kurangi jumlah build paralel Anda jika Anda tidak memiliki cukup RAM untuk mendukungnya. Jika build Anda mulai bertukar, Anda akan menjadi lebih lambat. Dengan make, coba -j4misalnya untuk 4 build paralel pada satu waktu.
Shahbaz
1
"Alexa

Jawaban:

84

Dalam pengalaman saya, Firefox dan Chrome menggunakan lebih banyak RAM daripada 7 komputer pertama saya yang digabungkan. Mungkin lebih dari itu, tetapi saya sudah jauh dari poin saya. Hal pertama yang harus Anda lakukan adalah menutup browser Anda . Sebuah perintah?

killall -9 firefox google-chrome google-chrome-stable chromium-browser

Saya telah mengikat browser paling populer menjadi satu perintah di sana, tetapi jelas jika Anda menjalankan sesuatu yang lain (atau tahu Anda tidak menggunakan salah satu dari ini) hanya memodifikasi perintah. Ini killall -9 ...adalah bagian yang penting. Orang-orang memang ragu-ragu tentang SIGKILL(nomor sinyal 9) tetapi browser sangat tangguh. Lebih dari itu, menghentikan secara lambat SIGTERMakan berarti browser melakukan banyak pembersihan sampah - yang membutuhkan ledakan RAM tambahan - dan itu adalah sesuatu yang Anda tidak mampu dalam situasi ini.

Jika Anda tidak bisa memasukkannya ke terminal yang sudah berjalan atau dialog Alt+ F2, pertimbangkan beralih ke TTY. Control+ Alt+ F2akan membawa Anda ke TTY2 yang memungkinkan Anda untuk masuk (meskipun mungkin lambat) dan bahkan harus membiarkan Anda menggunakan sesuatu seperti htopuntuk men-debug masalah. Saya tidak berpikir saya pernah kehabisan RAM sampai saya tidak bisa htopbangun.

Solusi jangka panjang mencakup membeli lebih banyak RAM, menyewanya melalui komputer jarak jauh, atau tidak melakukan apa yang sedang Anda lakukan. Saya akan menyerahkan argumen ekonomi yang rumit kepada Anda, tetapi secara umum, RAM murah untuk dibeli, tetapi jika Anda hanya perlu jumlah burst, server VPS ditagih per menit, atau jam adalah pilihan yang baik.

Oli
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
Thomas Ward
Saya mendapat beberapa perintah yang terhubung dengan perintah saya sendiri lazygityang saya gunakan dari waktu ke waktu, mungkin sesuatu seperti itu dapat diterapkan di sini? Keseluruhan killall ...skrip dapat direduksi menjadi sederhana emptyramatau semacamnya
Francisco Presencia
Anda tidak perlu menjalankan perintah lengkap jika Anda tahu browser apa yang sedang berjalan dan saya berasumsi kebanyakan orang yang dapat mengidentifikasi kekurangan RAM melakukannya. Dengan ekstensi, saya akan merasa lebih sulit untuk mengingat bahwa saya telah menulis sebuah emptyramskrip daripada sekadar menekan killall -9 firefox.
Oli
2
Membeli RAM ... mengapa tidak mengunduh lebih banyak RAM saja?
Stephan Bijzitter
1
Yah Anda mungkin bercanda tetapi jika Anda perlu melakukan sesuatu untuk waktu singkat yang membutuhkan lebih banyak RAM dan CPU yang Anda miliki, menyewa VPS setiap menit cukup ekonomis untuk satu tembakan.
Oli
66

Pada sistem dengan Kunci Permintaan Sistem Ajaib diaktifkan, menekan Alt + System Request+ f(jika tidak ditandai pada keyboard Anda, System Requestsering kali pada Print Screentombol tersebut) akan secara manual memanggil keluar dari memory killer (oomkiller) kernel, yang mencoba untuk memilih proses yang paling buruk untuk penggunaan memori dan bunuh. Anda dapat melakukan ini jika Anda memiliki waktu yang kurang dari yang telah Anda jelaskan dan sistem baru akan dimulai (atau mungkin sudah mulai) meronta-ronta - dalam hal ini Anda mungkin tidak peduli dengan pasti apa yang terbunuh, hanya saja Anda mengakhiri dengan sistem yang dapat digunakan. Kadang-kadang ini bisa berakhir dengan membunuh X, tetapi sebagian besar waktu ini jauh lebih baik dalam memilih proses yang buruk daripada sebelumnya.

Muzer
sumber
5
@ T.Sar jika Anda akan langsung meronta-ronta, Anda sudah kehilangan atau mendapatkan kesempatan untuk membunuh pemakan memori. Anda tidak mendapatkan apa-apa jika Anda hanya menahan diri dari akting.
Ruslan
4
@Muzer ini hanya akan berfungsi bila Anda telah menyetel kernel.sysrqke 1atau nomor termasuk bit yang benar di komputer Anda /etc/sysctl.d/10-magic-sysrq.conf.
Ruslan
9
@ T.Sar Anda tidak akan kehilangan progres jika Anda menggunakan sistem build waras. Anda akan menyimpan semua file objek tetapi yang Anda kompilasi sebenarnya, lalu Anda akan kembali ke tempat yang Anda tinggalkan.
Muzer
3
@ T.Sar Hanya karena hal yang Anda kompilasi tidak waras tidak berarti sistem build tidak waras. Membangun sistem sejak dahulu kala telah menyimpan file objek untuk digunakan kembali dalam kompilasi berikutnya. Di sisi lain, saya tentu dapat menyebutkan banyak proyek perangkat lunak dengan kewarasan yang lebih sedikit daripada Linux (yang umumnya dirancang dengan sangat baik). Sebagai contoh, mengkompilasi sesuatu seperti Firefox atau OpenOffice dengan 8 thread build paralel, saya dapat dengan mudah melihatnya dalam urutan gigabytes RAM. Ada juga banyak sistem perusahaan monolitik yang bergantung pada ratusan perpustakaan.
Muzer
7
@ T.Sar Linux tidak terlalu rumit dari POV kompiler. Sebenarnya hampir tidak ada program C yang ada. Bagaimana dengan C ++? Pernahkah Anda mencoba membuat program menggunakan Eigen atau Boost? Anda akan terkejut betapa banyak memori yang terkadang dikompilasi oleh kompiler dengan program-program semacam itu - dan mereka tidak harus menjadi kompleks sendiri.
Ruslan
20

Bertentangan dengan jawaban lain, saya sarankan Anda menonaktifkan swap saat Anda melakukan ini. Sementara swap membuat sistem Anda berjalan dengan cara yang dapat diprediksi, dan sering digunakan untuk meningkatkan throughput aplikasi mengakses disk (dengan mengusir halaman yang tidak digunakan untuk memberikan ruang bagi cache disk), dalam hal ini sepertinya sistem Anda sedang melambat ke tingkat yang tidak dapat digunakan karena terlalu banyak memori yang digunakan sedang diusir secara paksa untuk bertukar.

Saya akan merekomendasikan menonaktifkan swap sama sekali saat melakukan tugas ini, sehingga pembunuh kehabisan memori akan bertindak segera setelah RAM terisi.

Solusi alternatif:

  • Tingkatkan kecepatan baca swap dengan meletakkan partisi swap Anda di RAID1
    • Atau RAID0 jika Anda merasa berisiko tetapi itu akan menurunkan sejumlah besar program yang berjalan jika salah satu disk Anda rusak.
  • Kurangi jumlah pekerjaan bangun berbarengan ("core lebih banyak = lebih cepat", kita semua berkata, lupa bahwa dibutuhkan banyak linear pada RAM)
  • Ini bisa berjalan dua arah, tetapi coba aktifkan zswapdi kernel. Ini mengkompres halaman sebelum dikirim untuk bertukar, yang mungkin memberikan ruang gerak yang cukup untuk mempercepat mesin Anda. Di sisi lain, itu hanya bisa menjadi penghalang dengan kompresi / dekompresi tambahan yang dilakukannya.
  • Turunkan optimisasi atau gunakan kompiler yang berbeda. Mengoptimalkan kode terkadang dapat menghabiskan beberapa gigabytes memori. Jika Anda mengaktifkan LTO, Anda akan menggunakan banyak RAM pada tahap tautan juga. Jika semuanya gagal, Anda dapat mencoba mengkompilasi proyek Anda dengan kompiler berbobot lebih ringan (misalnya tcc), dengan mengorbankan sedikit kinerja runtime hit ke produk yang dikompilasi. (Ini biasanya dapat diterima jika Anda melakukan ini untuk tujuan pengembangan / debugging.)
Score_Under
sumber
6
Jika swap Anda dimatikan, itu adalah perilaku Linux ketika Anda kehabisan memori. Jika Linux tidak memanggil pembunuh kehabisan memori tetapi malah membeku, itu mungkin menandakan bahwa ada masalah yang lebih dalam dengan pengaturan. Tentu saja, jika swap dihidupkan, perilakunya sedikit berbeda.
Score_Di Bawah
10
@ Akiva Pernahkah Anda mencoba tanpa swap? Jawaban ini tepat. Saya ingin menambahkan bahwa menjalankan sudo swapoff -adapat menyelamatkan Anda ketika Anda sudah dalam keadaan terikat: itu akan segera menghentikan penggunaan ruang swap apa pun, yaitu pembunuh OOM harus dipanggil pada saat berikutnya dan membawa mesin ke dalam urutan kerja. sudo swapoff -ajuga merupakan tindakan pencegahan yang sangat baik ketika men-debug kebocoran memori atau mengkompilasi, katakanlah, firefox. Biasanya, swap sedikit berguna (misalnya untuk hibernasi atau menukar barang yang benar-benar tidak dibutuhkan), tetapi ketika Anda benar-benar menggunakan memori, pembekuannya lebih buruk.
Jonas Schäfer
2
@Score_Under: Partisi swap terpisah pada setiap disk seharusnya jauh lebih efisien daripada swap pada perangkat md raid0. Saya lupa di mana saya membacanya. Linux RAID wiki merekomendasikan partisi terpisah daripada raid0, tetapi tidak mengatakan sesuatu yang sangat kuat tentang mengapa itu lebih baik . Bagaimanapun ya, RAID1 atau RAID10n2 masuk akal untuk swap, terutama jika Anda kebanyakan hanya ingin dapat menukar beberapa halaman yang kotor tapi sangat dingin untuk meninggalkan lebih banyak RAM untuk pagecache. yaitu kinerja swap bukan masalah besar.
Peter Cordes
2
Maksud saya adalah bahwa mengikuti saran Anda, orang mungkin tidak dapat menjalankan program itu sama sekali, karena mereka perlu swap. Build yang gagal 100% lebih buruk daripada build yang memiliki peluang 50% untuk mengunci sistem, bukan?
Dmitry Grigoryev
2
Tanpa swap, pada banyak mesin tidak mungkin untuk mengkompilasi potongan kode besar. Mengapa Anda menganggap bahwa itu kompilasi yang ingin ia korbankan?
David Schwartz
14

Anda dapat menggunakan perintah berikut (berulang kali jika perlu) untuk mematikan proses menggunakan RAM terbanyak pada sistem Anda:

ps -eo pid --no-headers --sort=-%mem | head -1 | xargs kill -9

Dengan:

  • ps -eo pid --no-headers --sort=-%mem: menampilkan id proses semua proses yang berjalan, diurutkan berdasarkan penggunaan memori
  • head -1: hanya simpan baris pertama (proses menggunakan sebagian besar memori)
  • xargs kill -9: bunuh prosesnya

Edit setelah komentar akurat Dmitry:

Ini adalah solusi cepat dan kotor yang harus dijalankan ketika tidak ada tugas sensitif yang berjalan (tugas yang tidak Anda inginkan kill -9).

Gohu
sumber
5
Ini jauh lebih buruk daripada membiarkan pembunuh OOM menangani situasi. Pembunuh OOM jauh lebih pintar dari itu. Apakah Anda benar-benar menjalankan perintah seperti itu di komputer dengan kompilasi yang sedang berlangsung?
Dmitry Grigoryev
@DmitryGrigoryev, kadang-kadang sangat cerdas untuk membunuh Xorg di desktop saya. Dalam kernel modern, OOMK tampaknya telah mendapatkan kewarasan, tetapi saya tidak akan benar-benar mempercayainya.
Ruslan
11

Sebelum menjalankan perintah yang menghabiskan sumber daya Anda, Anda juga bisa menggunakan systemr setrlimit (2) , mungkin dengan ulimitbuiltin bash shell Anda (atau limitbuiltin di zsh) terutama dengan -vfor RLIMIT_AS. Kemudian konsumsi ruang alamat virtual terlalu besar (misalnya dengan mmap (2) atau sbrk (2) yang digunakan oleh malloc (3) ) akan gagal (dengan errno (3) sedang ENOMEM).

Kemudian mereka (yaitu proses lapar di shell Anda, setelah Anda mengetik ulimit) akan dihentikan sebelum membekukan sistem Anda.

Baca juga Linux Ate My RAM dan pertimbangkan untuk menonaktifkan overcommitment memori (dengan menjalankan perintah echo 0 > /proc/sys/vm/overcommit_memory sebagai root, lihat proc (5) ...).

Basile Starynkevitch
sumber
11

ini sering terjadi pada saya ketika saya sedang mengkompilasi perangkat lunak di latar belakang

Dalam hal itu, sesuatu seperti "killall -9 make" (atau apa pun yang Anda gunakan untuk mengelola kompilasi Anda, jika tidak membuat). Ini akan menghentikan proses kompilasi lebih lanjut, akan SIGHUP semua proses kompiler diluncurkan dari itu (mudah-mudahan menyebabkan mereka berhenti juga) dan, sebagai bonus, tidak perlu sudo dengan anggapan Anda mengkompilasi sebagai pengguna yang sama dengan yang Anda login sebagai. Dan karena membunuh penyebab sebenarnya dari masalah Anda alih-alih browser web Anda, sesi X atau beberapa proses secara acak, itu tidak akan mengganggu apa pun yang Anda lakukan pada sistem pada saat itu.

bulu-bulu
sumber
2
Sayang sekali saya harus menggulir ke bawah sejauh ini untuk menemukan jawaban ini. Saya berharap seseorang akan mengusulkan cara yang akan menunda kemajuan pemakan RAM ini.
TOOGAM
Bukan apa-apa di dekat jawaban yang diharapkan OP, tetapi menjawab pertanyaan sastra: mesin sampah saya tidak dapat digunakan ketika saya membangunnya - berhenti membangun di mesin sampah.
9ilsdx 9rvj 0lo
9

Buat lebih banyak swap untuk Anda sendiri.

Yang berikut ini akan menambah 8G swap:

dd if=/dev/zero of=/root/moreswap bs=1M count=8192
mkswap /root/moreswap
swapon /root/moreswap

Itu masih lambat (Anda bertukar) tetapi Anda seharusnya tidak benar-benar kehabisan. Versi modern Linux dapat bertukar ke file. Tentang penggunaan hanya untuk partisi swap hari ini adalah untuk hibernasi laptop Anda.

William Hay
sumber
1
Saya sudah menerapkan metode ini sebagai skrip, sebenarnya, di sini . Cukup berguna untuk menambahkan swap saat itu juga.
Sergiy Kolodyazhnyy
7
Beberapa swap umumnya bijaksana, tetapi mengalokasikan jumlah besar hanya membuat mesin meronta-ronta lebih banyak sebelum pembunuh OOM masuk dan memilih sukarelawan. Peran jempol tua tentang "menggandakan ram Anda sebagai swap" sudah lama mati. Secara pribadi saya tidak melihat nilai dalam mengalokasikan lebih dari ~ 1 GB total swap.
Criggie
5
Dengan ext4, Anda bisa fallocate -l 8G /root/moreswapbukannya ddmenghindari keharusan melakukan 8GB I / O saat sistem meronta-ronta. Ini tidak bekerja dengan sistem file lain. Jelas bukan XFS, di mana swapon melihat luasan tidak tertulis sebagai lubang. (Saya kira diskusi milis xfs ini tidak berjalan dengan baik). Lihat juga swapd, daemon yang membuat / menghapus file swap dengan cepat untuk menghemat ruang disk. Juga askubuntu.com/questions/905668/…
Peter Cordes
1
@Criggie "Secara pribadi saya tidak melihat nilai dalam mengalokasikan lebih dari ~ 1 GB total swap" - Sudahkah Anda mencoba membuat Firefox?
Dmitry Grigoryev
1
@ Akiva Terakhir kali saya memeriksa, konfigurasi build yang disarankan adalah 16 GB RAM. File yang dapat dieksekusi utama ( xul.dll) adalah sekitar 50 MB, jadi sekitar 10 kali lebih berat dari kernel Linux.
Dmitry Grigoryev
5

Salah satu cara untuk mendapatkan sepotong RAM gratis dalam waktu singkat adalah dengan menggunakan zram , yang menciptakan disk RAM terkompresi dan bertukar di sana. Dengan CPU setengah layak, ini jauh lebih cepat daripada swap biasa, dan tingkat kompresi cukup tinggi dengan banyak RAM RAM modern seperti browser web.

Dengan anggapan Anda telah menginstal dan mengkonfigurasi zram, yang harus Anda lakukan adalah menjalankan

sudo service zramswap start
Dmitry Grigoryev
sumber
Apakah ini berfungsi pada semua filesystem seperti btrfs?
Akiva
1
@Akiva zram tidak pernah menyentuh disk, jadi saya akan mengatakan ya;)
Dmitry Grigoryev
3

sudo swapoff -aakan menonaktifkan swap, membuat kernel secara otomatis membunuh proses dengan skor tertinggi jika sistem kehabisan memori. Saya menggunakan ini jika saya tahu saya akan menjalankan sesuatu RAM-berat yang saya lebih suka membunuh jika keluar dari kendali daripada membiarkannya masuk ke swap dan macet selamanya. Gunakan sudo swapon -auntuk mengaktifkannya kembali sesudahnya.

Kemudian, Anda mungkin ingin melihat pengaturan swap Anda. Kedengarannya swap Anda ada di disk yang sama dengan partisi root, yang akan memperlambat sistem Anda ketika Anda menekan swap, jadi hindari itu jika Anda bisa. Juga, menurut saya, sistem modern sering dikonfigurasi dengan terlalu banyak swap. RAM 32GiB biasanya berarti swap 32GiB dialokasikan secara default, seolah-olah Anda benar-benar ingin memasukkan 32GiB ke dalam ruang swap Anda.

sudo
sumber
Oh, saya baru saja melihat seseorang berkomentar di atas di suatu tempat.
sudo
3

Hal lain yang dapat dilakukan adalah membebaskan cache halaman memori melalui perintah ini:

echo 3 | sudo tee /proc/sys/vm/drop_caches

Dari dokumentasi kernel.org (penekanan ditambahkan):

drop_caches

Menulis ini akan menyebabkan kernel untuk menjatuhkan cache bersih, serta objek slab dapat direklamasi seperti gigi palsu dan inode. Setelah dijatuhkan, ingatan mereka menjadi bebas .

Untuk membebaskan pagecache: echo 1> / proc / sys / vm / drop_caches Untuk membebaskan objek slab yang dapat direklamasi (termasuk dentries dan inode): echo 2> / proc / sys / vm / drop_caches Untuk membebaskan objek slab dan pagecache: echo 3> / proc / sys / vm / drop_caches

Ini adalah operasi yang tidak merusak dan tidak akan membebaskan benda kotor. Untuk menambah jumlah objek yang dibebaskan oleh operasi ini, pengguna dapat menjalankan `sinkronisasi 'sebelum menulis ke / proc / sys / vm / drop_caches. Ini akan meminimalkan jumlah objek kotor pada sistem dan membuat lebih banyak kandidat untuk dijatuhkan.

Sergiy Kolodyazhnyy
sumber
Menarik ... peduli untuk menjelaskan logika perintah itu?
Akiva
1
@ Akiva pada dasarnya ini memberitahu kernel Linux untuk membebaskan RAM. Ini tidak menghilangkan penyebabnya, yang membunuh proses yang menyinggung, jadi jawaban Oli adalah solusi untuk masalah tersebut. Menjatuhkan cache akan mencegah sistem Anda kehabisan memori, karena itu mencegah pembekuan, sehingga memberi Anda waktu untuk mencari tahu masalah yang sebenarnya. Ini mungkin akan sedikit lebih cepat daripada membuat file swap, terutama jika Anda berada di hard drive dan bukan pada SSD
Sergiy Kolodyazhnyy
7
Cache adalah hal pertama yang harus Anda lakukan ketika Anda mengisi memori, jadi saya rasa ini tidak akan banyak membantu. Sebenarnya, saya tidak berpikir perintah ini memiliki penggunaan praktis di luar debugging perilaku kernel atau optimisasi akses disk waktu. Dengan rendah hati saya akan merekomendasikan untuk tidak menjalankan perintah ini pada sistem apa pun yang membutuhkan kinerja lebih.
Score_Di Bawah
2
@Score_Under - "Cache adalah hal pertama yang harus Anda lakukan ketika Anda mengisi memori" - yah, itu tergantung pada pengaturan Anda /proc/sys/vm/swappiness. Dengan swappiness diatur ke 0, Anda benar. Dengan pengaturan default 60, Anda sudah dekat. Namun dengan ditetapkan ke 200, bagaimanapun, itu akan menjadi halaman yang paling baru-baru ini digunakan dari proses yang berjalan yang dijatuhkan terlebih dahulu ... dalam kasus tertentu, perintah ini mungkin berguna. Tetapi menetapkan swappiness ke 0 (atau nilai rendah, mungkin 20 atau 30) akan menjadi pendekatan umum yang lebih baik.
Jules
3
@Score_Under Perintah ini berguna pada kernel lama dengan kswapdbug (beberapa orang bahkan membuat cronjobs dengannya). Tapi Anda benar, saya ragu itu akan membantu dengan pertanyaan ini.
Dmitry Grigoryev
1

Anda mengatakan "kompilasi di latar belakang". Apa yang kamu lakukan di latar depan? Jika Anda mengembangkannya dengan Eclipse atau sumber daya berat IDE lainnya, periksa apakah semuanya benar dihentikan di konsol.

Lingkungan pengembangan sering memungkinkan untuk memulai beberapa proses yang sedang dikembangkan, ini mungkin tetap menggantung juga setelah Anda tidak lagi tertarik pada mereka (dalam debugger, atau tidak selesai dengan baik). Jika pengembang tidak memperhatikan, puluhan proses yang terlupakan mungkin menumpuk di siang hari, menggunakan beberapa gigabyte secara bersamaan.

Periksa apakah semua yang harus diakhiri dalam IDE diakhiri.

h22
sumber