Blocco del computer su RAM quasi piena, possibilmente problema di cache del disco


75

Il problema secondo me è in qualche modo simile a questo thread.

Non importa se ho lo swap abilitato o disabilitato, ogni volta che la quantità di RAM effettivamente utilizzata inizia ad avvicinarsi al massimo e non c'è quasi spazio per la cache del disco, il sistema non risponde completamente.

Il disco gira selvaggiamente, e a volte dopo lunghe attese di 10-30 minuti si scioglierà, a volte no (o finisco la patente). A volte, se agisco rapidamente, riesco ad aprire lentamente la console e uccidere alcune delle applicazioni che mangiano ram come il browser, e il sistema si sblocca quasi istantaneamente.

A causa di questo problema non vedo quasi mai nulla nello scambio, solo a volte ci sono alcuni MB lì, e subito dopo appare questo problema. La mia ipotesi non così istruita sarebbe che sia in qualche modo collegato alla cache del disco troppo avida o alla gestione della memoria troppo clemente, quindi quando la memoria è necessaria non viene liberata abbastanza rapidamente e fa morire di fame il sistema.

Il problema può essere raggiunto molto velocemente se si lavora con file lagrge (500 MB +) che vengono caricati nella cache del disco e, successivamente, il sistema non è in grado di scaricarli abbastanza velocemente.

Qualsiasi aiuto o idea sarà molto apprezzato.

Per ora devo vivere nella paura costante, quando fare qualcosa che il computer può semplicemente congelare e di solito devo riavviarlo, se è davvero a corto di ram mi piacerebbe molto di più semplicemente uccidere alcune delle applicazioni dello spazio utente, come broser ( preferibilmente se potessi in qualche modo segnare quale uccidere per primo)

Anche se il mistero è il motivo per cui lo scambio non mi salva in questa situazione.

AGGIORNAMENTO: Non si è bloccato per un po 'di tempo, ma ora ho ripreso più volte. Ora tengo sempre il monitor RAM sul mio schermo e quando si è verificato l'hang ha mostrato ancora ~ 30% libero (usato probabilmente dalla cache del disco). Ulteriori sintomi: Se al momento sto guardando un video (lettore VLC) il suono si interrompe per primo, dopo alcuni secondi l'immagine si interrompe. Mentre il suono si è fermato, ho ancora un po 'di controllo sul PC, ma quando l'immagine si ferma non riesco più a muovere il mouse, quindi l'ho riavviato dopo qualche attesa. A proposito, questo non è accaduto quando ho iniziato a guardare il video ma un po 'di tempo in (20min) e non ho fatto altro in quel momento, anche se browser e oowrite erano aperti sul secondo schermo per tutto il tempo. Fondamentalmente qualcosa decide di accadere ad un certo punto e si blocca il sistema.

Come da richiesta nei commenti ho eseguito dmesg subito dopo il blocco. Non ho notato nulla di strano, ma non sapevo cosa cercare, quindi eccolo qui: https://docs.google.com/document/d/1iQih0Ee2DwsGd3VuQZu0bPbg0JGjSOCRZhu0B05CMYs/edit?hl=CzF7


11
Questo deve attirare più attenzione. So che ci sono bug archiviati da molti anni.
3

1
@ n3rd: questo è il bug .
Dan Dascalescu,

@ Krišjānis Nesenbergs: Per favore, correggimi se sbaglio, copiando anche un file lungo lo appendo.
Rick2047,

Grazie per aver posto questa domanda e aver trovato una soluzione. Aggiungi una data all'aggiornamento, altrimenti non è chiaro cosa ha funzionato e cosa non ha funzionato. Ho lo stesso problema, controllo sempre i livelli di memoria e ho 16 GB, sto pianificando di avere 32 GB, per vedere se riesco a risolverlo in quel modo ...
Beto Aveiga,

Risposte:


63

Per risolvere questo problema, ho scoperto che è necessario impostare la seguente impostazione su circa il 5% -6% della RAM fisica totale, divisa per il numero di core nel computer:

sysctl -w vm.min_free_kbytes=65536

Tieni presente che questa è un'impostazione per core, quindi se ho 2 GB di RAM e due core, ho calcolato il 6% di solo 1 GB e ho aggiunto un piccolo extra solo per sicurezza.

Ciò costringe il computer a provare a mantenere libera questa quantità di RAM e, in tal modo, limita la possibilità di memorizzare nella cache i file su disco. Ovviamente cerca ancora di memorizzarli nella cache e di sostituirli immediatamente, quindi dovresti probabilmente limitare anche lo scambio:

sysctl -w vm.swappiness=5

(100 = scambio il più spesso possibile, 0 = scambio solo sulla necessità totale)

Il risultato è che Linux non decide più in modo casuale di caricare un intero file di film di circa 1 GB di RAM mentre lo guarda e uccide la macchina nel farlo.

Ora c'è abbastanza spazio riservato per evitare la fame di memoria, che è stato il problema in modo evidente (visto che non ci sono più blocchi come prima).

Dopo un test per un giorno - i blocchi sono spariti, a volte ci sono piccoli rallentamenti, perché le cose vengono memorizzate nella cache più spesso, ma posso conviverci se non devo riavviare il computer ogni poche ore.

La lezione qui è - la gestione della memoria predefinita è solo uno dei casi d'uso e non è sempre la migliore, anche se alcune persone cercano di suggerire diversamente - Ubuntu per l'home entertainment dovrebbe essere configurato in modo diverso rispetto al server.


Probabilmente vuoi rendere permanenti queste impostazioni aggiungendole alle tue in /etc/sysctl.confquesto modo:

vm.swappiness=5
vm.min_free_kbytes=65536

1
Buona scoperta, prova a segnalare bug al riguardo, quindi c'è più consapevolezza del problema e spero che qualcuno troverà una soluzione per non caricare in modo casuale l'intero film,
Oxwivi,

grazie, grande dettaglio e spiega il mio problema. Molto apprezzato!
odedbd,

1
beh, ho provato quasi tutto, e solo il tuo suggerimento ha migliorato le cose. grazie
vitalii,

1
Se sto correndo senza una partizione di swap, dovrei usare una quantità maggiore del 5-6%? E l'impostazione vm.swappinessnon farà nulla in quel caso, suppongo?
Jarett Millard,

1
"[vm.min_free_kbytes] impone al computer di provare a mantenere libera questa quantità di RAM e, in tal modo, limita la possibilità di memorizzare nella cache i file su disco." - mi dispiace disturbare, ma questo non è legato a ciò che vm.min_free_kbytesfa affatto. Funziona come un blocco di pagine riservate per facilitare le __GFP_WAITallocazioni atomiche (cioè riempire o uccidere / non ) quando si è in contesa di memoria di sistema elevata. Si potrebbe in effetti ha senso alzare qui (come probabilmente queste bancarelle sono legati a quanto sostiene la memoria di sistema), ma non sarebbe certamente per la ragione descritta in questa risposta.
Chris Down,

9

Questo è successo per me in una nuova installazione di Ubuntu 14.04.

Nel mio caso, non aveva nulla a che fare con i problemi di sistema menzionati.

Invece, il problema era che l'UUID della partizione di swap era diverso durante l'installazione rispetto a dopo l'installazione. Quindi il mio scambio non è mai stato abilitato e la mia macchina si bloccherebbe dopo alcune ore di utilizzo.

La soluzione consisteva nel controllare l'UUID corrente della partizione di swap con

sudo blkid

e quindi sudo nano /etc/fstabper sostituire il valore UUID dello swap errato con quello riportato da blkid.

Un semplice riavvio per influenzare le modifiche e voilà.


3
Grazie mille! Ho lottato con questo bug incredibilmente esasperante per qualcosa da quasi un anno ormai, e avevo provato di tutto per risolverlo. Perché Linux ha questo comportamento? Sembra che dovrebbe comportarsi come se non ci fosse scambio e invocare il killer OOM. Invece, sembra far finta che ci sia swap, ma poi non riesce a scambiare effettivamente le cose (perché non c'è in realtà, dal momento che è configurato in modo errato).
crazy2be

@ crazy2be Non sta fallendo, sta funzionando all'infinito. Anche senza scambio, Linux può ancora eseguire il paging di programmi e file non modificati in memoria e rileggerli dal disco.
Martin Thornton,

5

So che questa domanda è vecchia, ma ho avuto questo problema in Ubuntu (Chrubuntu) 14.04 su un Chromebook Acer C720. Ho provato la soluzione di Krišjānis Nesenbergs, e ha funzionato un po ', ma a volte si è schiantato.

Alla fine ho trovato una soluzione che ha funzionato installando zram invece di usare lo scambio fisico sull'SSD. Per installarlo ho appena seguito le istruzioni qui , in questo modo:

sudo apt-get install zram-config

Successivamente sono stato in grado di configurare la dimensione dello swap zram modificando /etc/init/zram-config.confalla riga 21.

20: # Calculate the memory to user for zram (1/2 of ram)
21: mem=$(((totalmem / 2 / ${NRDEVICES}) * 1024))

Ho sostituito il 2 con un 1 per rendere le dimensioni dello zram le stesse dimensioni della quantità di ram che ho. Da allora non ho più avuto blocchi o mancata risposta del sistema.


zramè un'opzione valida solo se non è possibile installare più RAM. Se il sistema è troppo lento quando si passa a SSD e esce dalla RAM senza scambiare, allora zrampuò aiutare un po 'fino a quando si tenta di fare un po' di più e il risultato è lo stesso della RAM senza scambio.
Mikko Rantalainen,

5

Niente ha funzionato per me !!

Quindi ho scritto uno script per monitorare l'utilizzo della memoria. Tenterà innanzitutto di svuotare la cache RAM se il consumo di memoria aumenta una soglia. È possibile configurare questa soglia sullo script. Se anche il consumo di memoria non scende al di sotto della soglia, inizierà a uccidere i processi di uno in ordine decrescente di consumo di memoria fino a quando il consumo di memoria non sarà inferiore alla soglia. L'ho impostato al 96% per impostazione predefinita. È possibile configurarlo modificando il valore della variabile RAM_USAGE_THRESHOLD nello script.

Sono d'accordo che uccidere i processi che consumano memoria elevata non sia la soluzione perfetta, ma è meglio uccidere UNA applicazione invece di perdere TUTTO il lavoro !! lo script ti invierà una notifica desktop se l'utilizzo della RAM aumenta la soglia. Ti avviserà anche se uccide qualsiasi processo.

#!/usr/bin/env python
import psutil, time
import tkinter as tk
from subprocess import Popen, PIPE
import tkinter
from tkinter import messagebox
root = tkinter.Tk()
root.withdraw()

RAM_USAGE_THRESHOLD = 96
MAX_NUM_PROCESS_KILL = 100

def main():
    if psutil.virtual_memory().percent >= RAM_USAGE_THRESHOLD:
        # Clear RAM cache
        mem_warn = "Memory usage critical: {}%\nClearing RAM Cache".\
            format(psutil.virtual_memory().percent)
        print(mem_warn)
        Popen("notify-send \"{}\"".format(mem_warn), shell=True)
        print("Clearing RAM Cache")
        print(Popen('echo 1 > /proc/sys/vm/drop_caches',
                    stdout=PIPE, stderr=PIPE,
                    shell=True).communicate())
        post_cache_mssg = "Memory usage after clearing RAM cache: {}%".format(
                            psutil.virtual_memory().percent)
        Popen("notify-send \"{}\"".format(post_cache_mssg), shell=True)
        print(post_cache_mssg)

        if psutil.virtual_memory().percent < RAM_USAGE_THRESHOLD:
            print("Clearing RAM cache saved the day")
            return
        # Kill top C{MAX_NUM_PROCESS_KILL} highest memory consuming processes.
        ps_killed_notify = ""
        for i, ps in enumerate(sorted(psutil.process_iter(),
                                      key=lambda x: x.memory_percent(),
                                      reverse=True)):
            # Do not kill root
            if ps.pid == 1:
                continue
            elif (i > MAX_NUM_PROCESS_KILL) or \
                    (psutil.virtual_memory().percent < RAM_USAGE_THRESHOLD):
                messagebox.showwarning('Killed proccess - save_hang',
                                       ps_killed_notify)
                Popen("notify-send \"{}\"".format(ps_killed_notify), shell=True)
                return
            else:
                try:
                    ps_killed_mssg = "Killed {} {} ({}) which was consuming {" \
                                     "} % memory (memory usage={})". \
                        format(i, ps.name(), ps.pid, ps.memory_percent(),
                               psutil.virtual_memory().percent)
                    ps.kill()
                    time.sleep(1)
                    ps_killed_mssg += "Current memory usage={}".\
                        format(psutil.virtual_memory().percent)
                    print(ps_killed_mssg)
                    ps_killed_notify += ps_killed_mssg + "\n"
                except Exception as err:
                    print("Error while killing {}: {}".format(ps.pid, err))
    else:
        print("Memory usage = " + str(psutil.virtual_memory().percent))
    root.update()


if __name__ == "__main__":
    while True:
        try:
            main()
        except Exception as err:
            print(err)
        time.sleep(1)

Salvare il codice in un file dire save_hang.py. Esegui lo script come:

sudo python save_hang.py

Si noti che questo script è compatibile solo per Python 3 e richiede l'installazione del pacchetto tkinter. puoi installarlo come:

sudo apt-get install python3-tk

Spero che sia di aiuto...


2

La mia ipotesi è che tu abbia impostato vm.swappinessun valore molto basso, il che fa sì che il kernel si scambia troppo tardi, lasciando RAM troppo bassa per il funzionamento del sistema.

Puoi mostrare le tue attuali impostazioni di swappiness eseguendo:

sysctl vm.swappiness

Per impostazione predefinita, questo è impostato su 60. Ubuntu Wiki consiglia di impostarlo su 10, ma sentiti libero di impostarlo su un valore più alto. Puoi cambiarlo eseguendo:

sudo sysctl vm.swappiness=10

Questo lo cambierà solo per la sessione corrente , per renderlo persistente, è necessario aggiungere vm.swappiness = 10al /etc/sysctl.conffile.

Se il tuo disco è lento, prendi in considerazione l'acquisto di uno nuovo.


La riduzione effettiva della swapiness ha ridotto il problema (è accaduto più raramente). Lo tengo alle 5 ora. Anche se forse era un altro problema con higer swapinness, perché, quando avevo 60 anni, e ho deciso di guardare un film o modificare un file di grandi dimensioni, l'intero file di quasi un GB è stato caricato in memoria e quindi immediatamente il sistema ha iniziato a scambiare i programmi che ero utilizzando attivamente e persino l'interfaccia utente stessa. Il fatto è che penso di capire la parte di scambio, quello che voglio è uccidere avide applicazioni utente invece di congelare la macchina quando si esaurisce la RAM. (E preferibilmente limitare le dimensioni del file nella cache)
Krišjānis Nesenbergs,

@Krisa: quando il sistema esaurisce la memoria (RAM e scambio), il kernel chiama oom_kill che uccide i processi per risparmiare memoria. Sfortunatamente, non puoi controllare i processi target. Per attivarlo manualmente, premi Alt + SysRq + F. Quando esegui il dmesgcomando, dovresti vedere alcune informazioni (e il nome del processo + id) del processo. Penso che faresti meglio con l'acquisto di un nuovo disco più veloce. O aggiorna la tua RAM.
Lekensteyn,

3
Il problema è che oom_kill non viene chiamato prima che il computer sia bloccato per circa 30 minuti. Inoltre - c'è almeno un modo per sapere quale processo verrà ucciso per primo?
Krišjānis Nesenbergs,

2
Ho 2 GB di RAM e l'HDD è 5400rpm. Non credo davvero che sia un sistema così vecchio che giustifica il congelamento di mezz'ora mentre si guarda un video su un monitor e si sfogliano circa 20-30 schede nell'altro. In realtà sarei abbastanza felice se potessi sempre accedere alla console e uccidere alcuni processi - c'è un modo per rendere l'input dell'utente e il terminale estremamente prioritari in modo che funzioni mentre il sistema si blocca?
Krišjānis Nesenbergs,

1
Ad ogni modo, lo scambio e la quantità di RAM sono un po 'offtopici. Il problema è che quel sistema non risponde per molto tempo, anche se lo scambio è disabilitato, e dopo questo a volte esegue ancora il programma (quindi riesce a trovare memoria da qualche parte) e altre volte esegue oom_killer. Il sistema dovrebbe essere in grado di dire che si sta esaurendo la RAM e non lasciarmi eseguire più roba. Quindi c'è un modo per fermare quei blocchi o impostare la priorità dell'input dell'utente così in alto, che posso passare alla console quando si verificano e uccidere alcuni processi da solo?
Krišjānis Nesenbergs,

2

Ho lottato con questo problema per molto tempo, ma ora sembra essere risolto sul mio laptop.

Se nessuna delle altre risposte funziona per te (ho provato la maggior parte di esse), gioca con min_free_kbytes , per avere più spazio nella RAM quando il tuo computer inizia a scambiare (poco prima di colpire questo valore minimo sulla tua RAM libera).

Ho 16 GB di RAM, ma più presto che tardi la memoria si è riempita e poi ha smesso di rispondere per 10-30 minuti, fino a quando alcune cose non vengono scambiate.

Almeno per me, l'impostazione del valore min_free_kbytes al di sopra di quanto raccomandato rende il processo di scambio considerevolmente più veloce.

Per 16 GB di RAM, prova questo:

vm.min_free_kbytes=500000

Per impostare questo valore, vedere altre risposte o semplicemente cercarlo su Google :)


0

Gestisco costantemente uno dei miei laptop da una scheda SD Ubuntu live, con una piccola partizione di archiviazione ext4 e un file di scambio sul disco rigido. Quando viene utilizzata quasi tutta la RAM e il valore di swapiness è troppo basso (a volte preferisco tenere il disco rigido completamente spento se possibile, perché è rumoroso), le prestazioni di Linux tendono a cadere da una scogliera per me, in modo tale che TTY1 per uccidere Firefox richiede 15 minuti.

L'aumento /proc/sys/vm/vfs_cache_pressuredal valore predefinito di 100 a un valore di 6000 sembra aiutare a prevenire questo. Tuttavia, la documentazione del kernel avverte di non farlo, dicendo

Increasing vfs_cache_pressure significantly beyond 100 may have negative
performance impact. Reclaim code needs to take various locks to find freeable
directory and inode objects. With vfs_cache_pressure=1000, it will look for
ten times more freeable objects than there are.

Non sono del tutto sicuro degli effetti collaterali di questo, quindi starei attento a farlo.


Probabilmente otterrai risultati migliori con vfs_cache_pressurepiù vicino a 10 (cioè molto meno di 100) e impostando valori min_free_kbytespiù alti. Tieni presente che se si imposta min_free_kbytestroppo in alto, il killer OOM del kernel ucciderà tutti!
Mikko Rantalainen,

@MikkoRantalainen Ho già rilanciato min_free_kbytesa 262144 e ho notato che l'abbassamento vfs_cache_pressureha l'effetto opposto: abbassarlo al di sotto di 100 fa sì che il sistema non risponda molto più velocemente. Non sono sicuro del perché esattamente.
Hitechcomputergeek il

In generale, l'aumento vfs_cache_pressurecauserà il lancio delle directory prima del contenuto del file memorizzato nella cache e, di conseguenza, le prestazioni complessive subiranno di solito valori superiori a 100. Se riesci a capire i passaggi per riprodurre il sistema in crash / blocco a partire da, ad esempio, Ubuntu Live CD quindi gli sviluppatori del kernel possono capire la causa principale. Per me, l'hang si verifica senza alcun preavviso. La mia ipotesi migliore è che il kernel si blocchi a causa di OOM prima che OOM Killer abbia liberato abbastanza RAM. Ora sto eseguendo min_free_kbytes = 100000, admin_reserve_kbytes = 250000 e user_reserve_kbytes = 500000.
Mikko Rantalainen,

(cont) Non ho ancora avuto crash con la configurazione precedente anche se ho swappiness = 5 e vfs_cache_pressure = 20. Il sistema ha 16 GB di RAM e 8 GB di scambio su SSD. Un altro sistema ha 32 GB di RAM e zero swap e sembra casualmente soffrire dello stesso problema: premendo Alt + SysRq + f dopo che il sistema sembra lento sembra aiutare, quindi immagino che se OOM Killer agisse abbastanza velocemente il sistema non si bloccherebbe.
Mikko Rantalainen,
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.