Ubuntu sta esaurendo rapidamente la RAM e il mio computer sta iniziando a bloccarsi. Quale comando risolverà questo?


73

Mi succede abbastanza spesso quando sto compilando un software in background e improvvisamente tutto inizia a rallentare e alla fine si blocca [se non faccio nulla], poiché ho esaurito sia la RAM che lo spazio di scambio.

Questa domanda presuppone che io abbia abbastanza tempo e risorse per aprire Gnome Terminal, cercare nella mia cronologia ed eseguire un sudocomando.

Quale comando può salvarmi dal dover eseguire un riavvio forzato o qualsiasi riavvio?


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Thomas Ward

1
Se esaurisci lo spazio di swap, penso che tu ne abbia troppo poco. Ho ottenuto 20G di spazio di swap su questo computer. Il punto è che ti dà abbastanza tempo con un sistema utilizzabile per uccidere tutto ciò che sta divorando la tua memoria. Non è qualcosa in cui prendi solo ciò che utilizzerai, ma ciò che speri non utilizzerai mai.
JoL

1
Sei sicuro che sia la RAM che lo swap vengano riempiti? Se così fosse, il gestore OOM ucciderebbe il compilatore e libererebbe memoria (e rovinerebbe anche il processo di compilazione). Altrimenti, penso che si sta riempiendo, e forse il tuo sistema è lento perché lo scambio è sul tuo disco di sistema.
sudo,

3
Prova a ridurre il numero di build parallele se non hai abbastanza RAM per supportarlo. Se la tua build inizia a scambiare, sarai molto più lento. Con make, prova -j4ad esempio per 4 build parallele alla volta.
Shahbaz,

1
"Alexa order me 8 gigs of ram"

Risposte:


84

Nella mia esperienza, Firefox e Chrome usano più RAM dei miei primi 7 computer messi insieme. Probabilmente più di questo, ma mi sto allontanando dal mio punto. La prima cosa da fare è chiudere il browser . Un comando?

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

Ho collegato i browser più popolari in un solo comando lì, ma ovviamente se stai eseguendo qualcos'altro (o sai che non stai usando uno di questi) basta modificare il comando. Questa killall -9 ...è la parte importante. Le persone si arrabbiano SIGKILL(segnale numero 9) ma i browser sono estremamente resistenti. SIGTERMInoltre , terminare lentamente tramite significa che il browser esegue un sacco di rifiuti di pulizia, che richiedono un'esplosione di RAM aggiuntiva, ed è qualcosa che non puoi permetterti in questa situazione.

Se non riesci a inserirlo in un terminale già in esecuzione o in una Altfinestra di F2dialogo + , considera di passare a un TTY. Control+ Alt+ F2ti porterà a TTY2 che dovrebbe permetterti di accedere (anche se potrebbe essere lento) e dovrebbe anche permetterti di usare qualcosa di simile htopper eseguire il debug del problema. Non credo di aver mai esaurito la RAM al punto da non riuscire ad alzarmi htop.

La soluzione a lungo termine consiste nell'acquistare più RAM, noleggiarla tramite un computer remoto o non fare ciò che stai attualmente facendo. Lascerò a te gli intricati argomenti economici ma in generale, la RAM è economica da acquistare, ma se hai solo bisogno di una quantità di scoppio, un server VPS fatturato al minuto o l'ora è una buona scelta.


I commenti non sono per una discussione estesa; questa conversazione è stata spostata in chat .
Thomas Ward

Ho un paio di comandi collegati al mio lazygitcomando che utilizzo di volta in volta, forse qualcosa del genere potrebbe essere applicato qui? L'intero killall ...script potrebbe essere ridotto a un semplice emptyramo qualcosa del genere
Francisco Presencia,

Non è necessario eseguire il comando completo se si conosce il browser in uso e suppongo che la maggior parte delle persone in grado di identificare una carenza di RAM lo faccia. Per estensione, troverei più difficile ricordare che avevo scritto una emptyramsceneggiatura piuttosto che limitarmi a scrivere killall -9 firefox.
Oli

2
Acquistare RAM ... perché non scaricare più RAM?
Stephan Bijzitter,

1
Beh, potresti scherzare, ma se hai bisogno di fare qualcosa per un breve periodo che richiede molta più RAM e CPU che hai, noleggiare un VPS al minuto è abbastanza economico per un colpo solo.
Oli

66

Su un sistema con il Magic Request Request Key abilitato, premendo Alt + System Request+ f(se non è segnato sulla tastiera, System Requestè spesso sul Print Screentasto) si invocherà manualmente il killer di memoria esaurita del kernel (oomkiller), che tenta di scegliere il peggior processo offensivo per utilizzo della memoria e ucciderlo. Puoi farlo se hai forse meno tempo di quello che hai descritto e il sistema sta per iniziare (o forse ha già iniziato) il thrashing - nel qual caso probabilmente non ti interessa esattamente cosa viene ucciso, solo che finisci con un sistema utilizzabile. A volte questo può finire per uccidere X, ma la maggior parte delle volte in questi giorni è molto meglio scegliere un processo negativo rispetto al passato.


5
@ T.Sar se stai andando direttamente al thrashing, hai già perso o hai la possibilità di uccidere il mangiatore di memoria. Non ottieni nulla se ti astieni dalla recitazione.
Ruslan,

4
@Muzer questo funziona solo quando è stata impostata kernel.sysrqad 1o un numero compreso il bit corretto nel vostro /etc/sysctl.d/10-magic-sysrq.conf.
Ruslan,

9
@ T.Sar Non perderai i tuoi progressi se stai usando un sistema di build sano. Manterrai tutti i file oggetto tranne quello che stavi effettivamente compilando, quindi tornerai praticamente da dove eri rimasto.
Muzer,

3
@ T.Sar Solo perché la cosa che stai compilando non è sana non significa che il sistema di compilazione non sia sano. Costruisci sistemi da tempo immemorabile hanno archiviato file oggetto da riutilizzare nelle successive compilazioni. D'altra parte, posso certamente nominare molti progetti software con meno sanità mentale di Linux (che è generalmente piuttosto ben progettato). Ad esempio, compilando qualcosa come Firefox o OpenOffice con 8 thread di build paralleli, posso facilmente vederlo prendere nell'ordine dei gigabyte di RAM. Esistono anche molti sistemi monolitici aziendali che dipendono da centinaia di biblioteche.
Muzer,

7
@ T.Sar Linux non è molto complesso dal POV del compilatore. In realtà non ci sono quasi nessun programma C. Che dire di C ++? Hai mai provato a costruire un programma usando Eigen o Boost? Sareste sorpresi di quanta memoria a volte il compilatore consuma con tali programmi - e non devono essere complessi da soli.
Ruslan,

20

Contrariamente ad altre risposte, ti suggerisco di disabilitare lo swap mentre lo stai facendo. Mentre swap mantiene il sistema in esecuzione in modo prevedibile e viene spesso utilizzato per aumentare il throughput delle applicazioni che accedono al disco (eliminando le pagine inutilizzate per consentire spazio per la cache del disco), in questo caso sembra che il sistema venga rallentato a livelli inutilizzabili perché troppa memoria utilizzata attivamente viene sfrattata forzatamente per lo scambio.

Consiglierei di disabilitare del tutto lo swap mentre esegui questa attività, in modo che il killer di memoria insufficiente agisca non appena la RAM si riempie.

Soluzioni alternative:

  • Aumenta la velocità di lettura dello swap inserendo la tua partizione di swap in RAID1
    • Oppure RAID0 se ti senti rischioso ma ciò causerà un gran numero di programmi in esecuzione se uno dei tuoi dischi non funziona correttamente.
  • Diminuisci il numero di lavori di compilazione simultanei ("più core = più velocità", diciamo tutti, dimenticando che richiede un pedaggio lineare sulla RAM)
  • Questo potrebbe andare in entrambi i modi, ma prova ad abilitare zswapnel kernel. Questo comprime le pagine prima che vengano inviate allo scambio, il che può fornire lo spazio sufficiente per accelerare la macchina. D'altra parte, potrebbe finire per essere un ostacolo con la compressione / decompressione aggiuntiva che fa.
  • Abbassa le ottimizzazioni o usa un altro compilatore. L'ottimizzazione del codice a volte può richiedere diversi gigabyte di memoria. Se hai attivato LTO, utilizzerai molta RAM anche nella fase di collegamento. Se tutto il resto fallisce, puoi provare a compilare il tuo progetto con un compilatore più leggero (ad es. tcc), A scapito di una leggera riduzione delle prestazioni di runtime sul prodotto compilato. (Questo è generalmente accettabile se lo fai per scopi di sviluppo / debug.)

6
Se lo scambio è disattivato, questo è il comportamento di Linux quando si esaurisce la memoria. Se Linux non invoca il killer di memoria insufficiente ma si blocca, ciò potrebbe significare che ci sono problemi più profondi con l'installazione. Naturalmente, se lo swap è attivato, il comportamento è leggermente diverso.
Score_Under

10
@Akiva Hai mai provato senza scambiare? Questa risposta è perfetta. Vorrei aggiungere che la corsa sudo swapoff -apotrebbe salvarti quando sei già in un bind: interromperà immediatamente qualsiasi ulteriore utilizzo dello spazio di swap, ovvero il killer OOM dovrebbe essere invocato nell'istante successivo e riportare la macchina in ordine. sudo swapoff -aè anche un'ottima misura precauzionale durante il debug di perdite di memoria o la compilazione, diciamo, di Firefox. Normalmente, lo scambio è un po 'utile (ad esempio per l'ibernazione o lo scambio di cose davvero non necessarie), ma quando si utilizza effettivamente la memoria, i blocchi sono peggiori.
Jonas Schäfer il

2
@Score_Under: le partizioni di swap separate su ciascun disco dovrebbero essere significativamente più efficienti dello swap su un dispositivo md raid0. Dimentico dove l'ho letto. Il wiki RAID Linux raccomanda partizioni separate rispetto a raid0, ma non dice nulla di molto forte sul perché sia ​​meglio . Comunque sì, RAID1 o RAID10n2 hanno senso per lo scambio, specialmente se per lo più vuoi solo essere in grado di scambiare alcune pagine sporche ma molto fredde per lasciare più RAM per il pagecache. cioè le prestazioni di swap non sono un grosso problema.
Peter Cordes,

2
Il mio punto è che, seguendo i tuoi consigli, potresti non essere in grado di eseguire quei programmi, perché hanno bisogno di essere scambiati. Una build che fallisce il 100% delle volte è peggio di una build che ha il 50% di probabilità di bloccare il sistema, no?
Dmitry Grigoryev il

2
Senza swap, su molte macchine è impossibile compilare grossi blocchi di codice. Perché dovresti presumere che sia la compilazione che vuole sacrificare?
David Schwartz,

14

Puoi usare il seguente comando (ripetutamente se necessario) per terminare il processo usando la maggior quantità di RAM sul tuo sistema:

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

Con:

  • ps -eo pid --no-headers --sort=-%mem: visualizza gli ID di processo di tutti i processi in esecuzione, ordinati per utilizzo della memoria
  • head -1: mantiene solo la prima riga (processo che utilizza la maggior quantità di memoria)
  • xargs kill -9: termina il processo

Modifica dopo il preciso commento di Dmitry:

Questa è una soluzione rapida e sporca che dovrebbe essere eseguita quando non ci sono attività sensibili in esecuzione (attività che non si desidera kill -9).


5
Questo è molto peggio che lasciare che l'assassino OOM gestisca la situazione. Il killer OOM è molto più intelligente di così. Esegui davvero tali comandi su un computer con compilazioni in corso?
Dmitry Grigoryev il

@DmitryGrigoryev è così intelligente a volte uccidere Xorg sul mio desktop. Nei kernel moderni OOMK sembra aver guadagnato un po 'di buonsenso, ma dopo tutto ciò non mi fiderei davvero.
Ruslan,

11

Prima di eseguire i comandi che consumano risorse, è possibile utilizzare anche la chiamata di sistema setrlimit (2) , probabilmente con l' ulimitintegrato della shell bash (o l' limitintegrato in zsh), in particolare con -vfor RLIMIT_AS. Quindi il consumo di spazio di indirizzi virtuali troppo grande (ad es. Con mmap (2) o sbrk (2) usato da malloc (3) ) fallirà ( essendo errno (3)ENOMEM ).

Quindi (cioè i processi affamati nella tua shell, dopo averli digitati ulimit) sarebbero terminati prima di congelare il sistema.

Leggi anche Linux Ate My RAM e considera la disabilitazione del sovraccarico di memoria (eseguendo il comando echo 0 > /proc/sys/vm/overcommit_memory come root, vedi proc (5) ...).


11

questo succede abbastanza spesso a me quando sto compilando software in background

In tal caso, qualcosa come "killall -9 make" (o qualunque cosa tu stia usando per gestire la tua compilation, se non crea). Questo interromperà la compilazione procedendo ulteriormente, SIGHUP tutti i processi del compilatore avviati da esso (sperando che si fermino anche loro) e, come bonus, non è necessario sudo supponendo che tu stia compilando come lo stesso utente a cui sei collegato in come. E poiché uccide la causa effettiva del problema anziché il browser Web, la sessione X o qualche processo a caso, non interferirà con qualsiasi altra cosa stiate facendo sul sistema in quel momento.


2
è un peccato che ho dovuto scorrere così in basso per trovare questa risposta. Speravo che qualcuno potesse proporre un modo per sospendere i progressi su questo mangiatore di RAM.
TOOGAM,

Non c'è niente vicino alla risposta che OP si aspetta, ma risponde alla domanda letteraria: la mia macchina da schifo è resa inutilizzabile quando ci costruisco sopra - smetti di costruire su macchina da schifo.
9ilsdx 9rvj 0lo,

9

Crea altro swap per te stesso.

Quanto segue aggiungerà 8G di swap:

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

Sarà comunque lento (stai scambiando) ma non dovresti davvero finire. Le versioni moderne di Linux possono passare ai file. Al giorno d'oggi l'unico uso per una partizione di swap è l'ibernazione del laptop.


1
Ho questo metodo implementato come uno script, in realtà, qui . Abbastanza utile per aggiungere swap al volo.
Sergiy Kolodyazhnyy,

7
Uno scambio è generalmente saggio, ma l'allocazione di grandi quantità consente semplicemente alla macchina di colpire di più prima che l'assassino OOM intervenga e scelga un volontario. Il vecchio e lugubre ruolo di "raddoppiare il montone come scambio" è morto da tempo. Personalmente non vedo alcun valore nell'allocare più di ~ 1 GB di scambio totale.
Criggie

5
Con ext4, puoi fallocate -l 8G /root/moreswapinvece di ddevitare di dover fare 8 GB di I / O mentre il sistema è in crash. Tuttavia, questo non funziona con nessun altro filesystem. Sicuramente non XFS, dove swapon vede le estensioni non scritte come buchi. (Immagino che questa discussione sulla mailing list di xfs non sia andata a buon fine). Vedi anche swapd, un demone che crea / rimuove i file di scambio al volo per risparmiare spazio su disco. Anche askubuntu.com/questions/905668/…
Peter Cordes,

1
@Criggie "Personalmente non vedo alcun valore nell'allocare più di ~ 1 GB di scambio totale" - Hai provato a creare Firefox?
Dmitry Grigoryev il

1
@Akiva L'ultima volta che ho verificato, la configurazione di build consigliata era di 16 GB di RAM. Il file eseguibile principale ( xul.dll) è di circa 50 MB, quindi è circa 10 volte più pesante del kernel Linux.
Dmitry Grigoryev il

5

Un modo per ottenere un pezzo di RAM libera in breve tempo è usare zram , che crea un disco RAM compresso e scambia lì. Con qualsiasi CPU decente, questo è molto più veloce del normale scambio e i tassi di compressione sono piuttosto alti con molti maiali RAM moderni come i browser web.

Supponendo che tu abbia installato e configurato zram, tutto ciò che devi fare è eseguire

sudo service zramswap start

Funziona su tutti i filesystem come btrfs?
Akiva,

1
@Akiva zram non tocca mai il disco, quindi direi di sì;)
Dmitry Grigoryev

3

sudo swapoff -adisabiliterà lo scambio, facendo sì che il kernel uccida automaticamente il processo con il punteggio più alto se il sistema esaurisce la memoria. Lo uso se so che avrò qualcosa di pesantemente RAM che preferirei uccidere se va fuori controllo piuttosto che lasciarlo andare in scambio e rimanere bloccato per sempre. Utilizzare sudo swapon -aper riattivarlo in seguito.

Successivamente, potresti dare un'occhiata alle tue impostazioni di scambio. Sembra che lo swap si trovi sullo stesso disco della partizione root, il che rallenterebbe il sistema quando si esegue lo swap, quindi evitarlo se è possibile. Inoltre, a mio avviso, i sistemi moderni spesso si configurano con troppi swap. La RAM 32GiB di solito significa che lo swap 32GiB è allocato per impostazione predefinita, come se volessi davvero inserire 32GiB nel tuo spazio di swap.


Oh, ho appena visto che qualcuno lo ha commentato sopra da qualche parte.
sudo,

3

Un'altra cosa che si potrebbe fare è liberare la cache della pagina di memoria tramite questo comando:

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

Dalla documentazione di kernel.org (enfasi aggiunta):

drop_caches

Scrivere in questo modo farà sì che il kernel rilasci cache pulite, oltre a oggetti di lastra recuperabili come dentisti e inode. Una volta rilasciati, la loro memoria diventa libera .

Per liberare pagecache: echo 1> / proc / sys / vm / drop_caches Per liberare oggetti slab recuperabili (include dentices e inode): echo 2> / proc / sys / vm / drop_caches Per liberare oggetti slab e pagecache: echo 3> / proc / sys / vm / drop_caches

Questa è un'operazione non distruttiva e non libererà alcun oggetto sporco. Per aumentare il numero di oggetti liberati da questa operazione, l'utente può eseguire `sync 'prima di scrivere su / proc / sys / vm / drop_caches. Ciò ridurrà al minimo il numero di oggetti sporchi sul sistema e creerà più candidati da eliminare.


Interessante ... ti interessa spiegare quella logica di comando?
Akiva,

1
@Akiva in pratica questo dice al kernel Linux di liberare la RAM. Questo non elimina la causa, che sta uccidendo il processo offensivo, quindi la risposta di Oli è la soluzione al problema. Eliminare le cache impedirà al sistema di esaurire la memoria, quindi impedire il congelamento, risparmiando così tempo per capire il problema reale. Questo probabilmente sarà un po 'più veloce rispetto alla creazione di un file di scambio, specialmente se sei su disco rigido e non su SSD
Sergiy Kolodyazhnyy,

7
La cache è la prima cosa da fare quando si riempie la memoria, quindi non credo che questo ti aiuterà molto. In realtà, non credo che questo comando abbia un uso pratico al di fuori del comportamento del kernel di debug o delle ottimizzazioni dell'accesso al disco di temporizzazione. Consiglio vivamente di non eseguire questo comando su qualsiasi sistema che necessita di maggiori prestazioni.
Score_Under

2
@Score_Under - "La cache è la prima cosa da fare quando si riempie la memoria" - beh, dipende dall'impostazione /proc/sys/vm/swappiness. Con lo swappiness impostato su 0, hai ragione. Con l'impostazione predefinita di 60, sei vicino. Se è impostato su 200, tuttavia, saranno le pagine dei processi in esecuzione utilizzate meno di recente che verranno eliminate per prime ... in quel caso particolare, questo comando può essere utile. Ma impostare lo swappiness su 0 (o un valore basso, forse 20 o 30) sarebbe un approccio generale migliore, comunque.
Jules il

3
@Score_Under Questo comando è stato utile su kernel vecchi con kswapdbug (alcune persone hanno persino creato cronjobs con esso). Ma hai ragione, dubito che aiuterà con questa domanda.
Dmitry Grigoryev il

1

Hai detto "compilazione in background". Cosa stai facendo in primo piano? Se si sta sviluppando con Eclipse o altre risorse IDE pesanti, verificare che tutto sia correttamente terminato nella console.

Gli ambienti di sviluppo spesso consentono di avviare più processi in fase di sviluppo, questi possono rimanere sospesi anche dopo che non sono più interessati a loro (nel debugger o semplicemente non completati correttamente). Se lo sviluppatore non presta attenzione, durante il giorno possono accumularsi decine di processi dimenticati, utilizzando contemporaneamente più gigabyte.

Controlla se tutto ciò che dovrebbe essere terminato in IDE è terminato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.