Komputer zawiesza się na prawie pełnej pamięci RAM, prawdopodobnie problem z pamięcią podręczną dysku

74

Problem, który moim zdaniem jest nieco podobny do tego wątku.

Nie ma znaczenia, czy mam włączoną lub wyłączoną zamianę, ilekroć rzeczywista wykorzystana ilość pamięci RAM zaczyna zbliżać się do maksimum i prawie nie ma już miejsca na pamięć podręczną dysku, system całkowicie przestaje odpowiadać.

Dysk obraca się dziko i czasami po długich odczekaniach 10-30 minut odmrozi, a czasem nie (lub zabraknie mi cierpliwości). Czasami, jeśli działam szybko, potrafię powoli otworzyć konsolę i zabić niektóre aplikacje wykorzystujące barana, takie jak przeglądarka, a system od razu się zawiesza.

Z powodu tego problemu prawie nigdy nie widzę niczego w zamianie, tylko czasami jest tam kilka MB, a wkrótce potem pojawia się ten problem. Domyślam się, że nie jest tak dobrze wykształcony, że jest on w jakiś sposób podłączony do zbyt chciwej pamięci podręcznej dysku lub zbyt łagodnego zarządzania pamięcią, więc kiedy pamięć jest potrzebna, nie jest wystarczająco szybko zwalniana i głodzi system.

Problem można rozwiązać naprawdę szybko, jeśli pracujesz z plikami lagrge (500 MB +), które są ładowane do pamięci podręcznej dysku i pewnie potem system nie jest w stanie ich wystarczająco szybko rozładować.

Każda pomoc lub pomysły będą mile widziane.

Na razie muszę żyć w ciągłym strachu, kiedy robiąc coś, komputer może po prostu zawiesić się i zwykle muszę go ponownie uruchomić, jeśli naprawdę kończy się RAM, wolałbym zabić niektóre aplikacje przestrzeni użytkownika, takie jak broser ( najlepiej gdybym mógł jakoś oznaczyć, który zabić jako pierwszy)

Chociaż tajemnicą jest to, dlaczego zamiana nie ratuje mnie w tej sytuacji.

AKTUALIZACJA: Przez pewien czas się nie zawieszał, ale teraz znów mam kilka wystąpień. Teraz cały czas trzymam monitor RAM na ekranie, a kiedy się zawiesił, nadal pokazywał ~ 30% wolnego (prawdopodobnie używany przez pamięć podręczną dysku). Dodatkowe objawy: Jeśli w czasie oglądania wideo (odtwarzacz VLC) dźwięk przestaje być pierwszy, po kilku sekundach obraz się zatrzymuje. Podczas gdy dźwięk się zatrzymał, nadal mam pewną kontrolę nad komputerem, ale kiedy obraz się zatrzymuje, nie mogę już nawet ruszyć myszy, więc uruchomiłem go ponownie po pewnym czasie. Przy okazji, tak się nie stało, kiedy zacząłem oglądać wideo, ale jakiś czas później (20 minut) i wtedy nie robiłem nic innego, mimo że przeglądarka i oowrite były cały czas otwarte na drugim ekranie. Zasadniczo coś po prostu decyduje się wydarzyć w pewnym momencie i zawiesza system.

Zgodnie z prośbą w komentarzach uruchomiłem dmesg zaraz po zawieszeniu. Nie zauważyłem niczego dziwnego, ale nie wiedziałem, czego szukać, więc oto: https://docs.google.com/document/d/1iQih0Ee2DwsGd3VuQZu0bPbg0JGjSOCRZhu0B05CMYs/edit?hl=pl_US&authkey=CPzF7bcC

Krišjānis Nesenbergs
źródło
11
To wymaga większej uwagi. Wiem, że błędy zgłaszane są przez wiele lat.
n3rd
1
@ n3rd: To jest błąd .
Dan Dascalescu
@ Krišjānis Nesenbergs: Popraw mnie, jeśli się mylę, kopiowanie wklejenia długiego pliku powoduje również jego zawieszenie.
Rick2047,
Dziękujemy za zadanie tego pytania i znalezienie rozwiązania. Dodaj datę aktualizacji, w przeciwnym razie nie jest jasne, co zadziałało, a co nie. Mam ten sam problem, zawsze sprawdzam poziomy pamięci i mam 16 GB, planuję mieć 32 GB, aby zobaczyć, czy mogę to naprawić w ten sposób ...
Beto Aveiga,

Odpowiedzi:

63

Aby rozwiązać ten problem, stwierdziłem, że musisz ustawić następujące ustawienie na około 5% -6% całkowitej fizycznej pamięci RAM, podzielone przez liczbę rdzeni w komputerze:

sysctl -w vm.min_free_kbytes=65536

Pamiętaj, że jest to ustawienie na rdzeń, więc jeśli mam 2 GB pamięci RAM i dwa rdzenie, to obliczyłem 6% tylko 1 GB i dodałem trochę więcej, aby być bezpiecznym.

Zmusza to komputer do próby utrzymania tej ilości wolnej pamięci RAM, a przez to ogranicza możliwość buforowania plików na dysku. Oczywiście nadal próbuje je buforować i natychmiast je wymieniać, więc prawdopodobnie powinieneś również ograniczyć swoje zamiany:

sysctl -w vm.swappiness=5

(100 = zamień tak często, jak to możliwe, 0 = zamień tylko w razie konieczności)

Powoduje to, że linux nie decyduje już losowo o załadowaniu całego pliku filmowego o wielkości około 1 GB w pamięci RAM podczas oglądania go i zabijając przy tym maszynę.

Teraz jest wystarczająca ilość miejsca, aby uniknąć głodu pamięci, co zwykle było problemem (ponieważ nie ma już takich zawieszeń jak wcześniej).

Po całodniowym testowaniu - zawieszanie się minęło, czasem dochodzi do niewielkich spowolnień, ponieważ rzeczy są buforowane częściej, ale mogę z tym żyć, jeśli nie muszę restartować komputera co kilka godzin.

Lekcja jest taka - domyślne zarządzanie pamięcią jest tylko jednym z przypadków użycia i nie zawsze jest najlepsze, chociaż niektórzy próbują sugerować inaczej - ubuntu domowej rozrywki powinno być skonfigurowane inaczej niż serwer.


Prawdopodobnie chcesz, aby te ustawienia były trwałe, dodając je do swojego /etc/sysctl.conf:

vm.swappiness=5
vm.min_free_kbytes=65536
Krišjānis Nesenbergs
źródło
Dobre znalezisko, spróbuj zgłosić błędy na ten temat, aby zwiększyć świadomość problemu i mam nadzieję, że ktoś
wymyśli
dzięki, bardzo szczegółowo i wyjaśnia mój problem. Bardzo mile widziane!
odedbd
1
cóż, próbowałem prawie wszystkiego i tylko twoja sugestia poprawiła rzeczy. dziękuję
vitalii
1
Jeśli działam bez partycji wymiany, czy powinienem użyć większej ilości niż 5-6%? vm.swappinessZakładam, że ustawienie nic nie da w tym przypadku, zakładam?
Jarett Millard,
1
„[vm.min_free_kbytes] zmusza komputer do próby utrzymania tej ilości wolnej pamięci RAM, co ogranicza możliwości buforowania plików na dysku.” - przepraszam, że przeszkadzam, ale to wcale nie jest związane z tym, co vm.min_free_kbytesrobi. Działa jak blok stron zarezerwowany w celu ułatwienia __GFP_WAITprzydziałów atomowych (tj. Wypełniania lub zabijania / nie ), gdy występuje duża rywalizacja o pamięć systemową. To mogłoby rzeczywiście sensu go podnieść tutaj (jak zapewne te stragany są związane z twierdzeniem pamięci systemowej), ale na pewno nie będzie z tego powodu opisanego w tej odpowiedzi.
Chris Down,
9

Stało się to dla mnie w nowej instalacji Ubuntu 14.04.

W moim przypadku nie miało to nic wspólnego z wymienionymi problemami sysctl.

Problem polegał na tym, że identyfikator UUID partycji wymiany był inny podczas instalacji niż po instalacji. Tak więc moja zamiana nigdy nie była włączona, a moja maszyna blokowała się po kilku godzinach użytkowania.

Rozwiązanie było sprawdzenie aktualnego UUID partycji SWAP z

sudo blkid

a następnie, sudo nano /etc/fstababy zastąpić wartość UUID niepoprawnej zamiany wartością zgłoszoną przez blkid.

Prosty restart, aby wpłynąć na zmiany i voila.

Dale Anderson
źródło
3
Dziękuję bardzo! Walczę z tym niesamowicie irytującym błędem już od prawie roku i próbowałem wszystkiego, aby to naprawić. Dlaczego Linux ma takie zachowanie? Wygląda na to, że powinien zachowywać się tak, jakby nie było zamiany, i po prostu przywołaj zabójcę OOM. Zamiast tego wydaje się, że udaje, że istnieje zamiana, ale nie udaje jej się zamienić (bo tak naprawdę nie ma, ponieważ jest źle skonfigurowana).
crazy2be,
@ crazy2be To nie zawodzi, to się nie kończy. Nawet bez wymiany Linux nadal może wyświetlać programy i niezmodyfikowane pliki w pamięci i ponownie odczytywać je z dysku.
Martin Thornton
4

Wiem, że to pytanie jest stare, ale miałem ten problem w Ubuntu (Chrubuntu) 14.04 na Chromebooku Acer C720. Wypróbowałem rozwiązanie Krišjānis Nesenbergs i działało to trochę, ale czasami ulegało awarii.

W końcu znalazłem rozwiązanie, które działało, instalując zram zamiast korzystania z fizycznej wymiany na dysku SSD. Aby go zainstalować, postępowałem zgodnie z instrukcjami tutaj :

sudo apt-get install zram-config

Potem mogłem skonfigurować rozmiar zamiany zram poprzez modyfikację /etc/init/zram-config.confw linii 21.

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

Zamieniłem 2 na 1, aby rozmiar ZRAM był taki sam, jak ilość pamięci RAM. Od tego czasu nie zawieszałem się ani nie reagowałem na system.

brizmut
źródło
zramjest wykonalna opcja tylko wtedy, gdy nie można zainstalować więcej pamięci RAM. Jeśli system jest zbyt wolny podczas zamiany na SSD i wychodzi z pamięci RAM bez zamiany, zrammoże to trochę pomóc, dopóki nie spróbujesz zrobić czegoś więcej, a wynik będzie taki sam, jak z pamięci RAM bez zamiany.
Mikko Rantalainen,
4

Nic mi nie działało !!

Napisałem więc skrypt do monitorowania zużycia pamięci. Najpierw spróbuje wyczyścić pamięć podręczną RAM, jeśli zużycie pamięci zwiększy próg. Możesz skonfigurować ten próg w skrypcie. Jeśli zużycie pamięci nie spadnie nawet poniżej tego progu, rozpocznie proces zabijania jeden po drugim w malejącym porządku zużycia pamięci, aż zużycie pamięci spadnie poniżej progu. Domyślnie ustawiłem go na 96%. Możesz go skonfigurować, zmieniając wartość zmiennej RAM_USAGE_THRESHOLD w skrypcie.

Zgadzam się, że zabijanie procesów zużywających dużo pamięci nie jest idealnym rozwiązaniem, ale lepiej jest zabić JEDNĄ aplikację, niż stracić CAŁĄ pracę !! skrypt wyśle ​​Ci powiadomienie na pulpicie, jeśli użycie pamięci RAM podniesie próg. Powiadomi Cię również, jeśli zabije jakikolwiek proces.

#!/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)

Zapisz kod w pliku, powiedz save_hang.py. Uruchom skrypt jako:

sudo python save_hang.py

Uwaga: ten skrypt jest kompatybilny tylko z Python 3 i wymaga instalacji pakietu tkinter. możesz zainstalować jako:

sudo apt-get install python3-tk

Mam nadzieję że to pomoże...

Saim Raza
źródło
2

Domyślam się, że ustawiłeś vm.swappinessbardzo niską wartość, co powoduje, że jądro zamienia się zbyt późno, pozostawiając zbyt mało pamięci RAM do pracy z systemem.

Możesz pokazać swoje obecne ustawienie swapiness, wykonując:

sysctl vm.swappiness

Domyślnie jest on ustawiony na 60. Wiki Ubuntu zaleca ustawienie go na 10, ale możesz ustawić wyższą wartość. Możesz to zmienić, uruchamiając:

sudo sysctl vm.swappiness=10

Spowoduje to zmianę tylko dla bieżącej sesji , aby była trwała, musisz dodać vm.swappiness = 10do /etc/sysctl.confpliku.

Jeśli twój dysk jest wolny, rozważ zakup nowego.

Lekensteyn
źródło
Właściwie zmniejszenie zamiany zmniejszyło problem (zdarzało się to rzadziej). Trzymam teraz na 5. Chociaż może był to kolejny problem z wyższą zamianą, ponieważ kiedy miał 60 lat i postanowiłem obejrzeć film lub edytować duży plik, cały plik i prawie GB został załadowany do pamięci, a następnie natychmiast system zaczął wymieniać programy, którymi byłem aktywnie korzysta, a nawet sam interfejs użytkownika. Chodzi o to, że myślę, że rozumiem część zamienną. Chcę zabijać chciwe aplikacje użytkownika zamiast zamrażać maszynę, gdy kończy się RAM. (I najlepiej ograniczyć rozmiar pliku w pamięci podręcznej)
Krišjānis Nesenbergs
@Krisa: gdy w systemie zabraknie pamięci (RAM i swap), jądro wywołuje oom_kill, który zabija procesy w celu oszczędzania pamięci. Niestety nie można kontrolować procesów docelowych. Aby uruchomić go ręcznie, naciśnij klawisze Alt + SysRq + F. Po uruchomieniu dmesgpolecenia powinny zostać wyświetlone pewne informacje (oraz nazwa procesu + identyfikator) procesu. Myślę, że lepiej byłoby kupić nowy, szybszy dysk. Lub zaktualizuj swoją pamięć RAM.
Lekensteyn,
3
Problem polega na tym, że oom_kill po prostu nie zostaje wywołany, zanim komputer zostanie zamknięty na około 30 minut. Ponadto - czy jest przynajmniej sposób, aby wiedzieć, który proces zostanie zabity jako pierwszy?
Krišjānis Nesenbergs
2
Mam 2 GB pamięci RAM, a dysk twardy to 5400 obr./min. Naprawdę nie sądzę, że jest to tak stary system, który usprawiedliwia pół godziny zawieszania się podczas oglądania wideo na jednym monitorze i przeglądania około 20-30 kart na drugim. Byłbym naprawdę szczęśliwy, gdybym mógł zawsze uzyskać dostęp do konsoli i zabić niektóre procesy - czy istnieje sposób, aby wprowadzanie danych przez użytkownika i terminal miało najwyższy priorytet, aby działało, gdy system zawiesza się?
Krišjānis Nesenbergs
1
W każdym razie - wymiana i ilość pamięci RAM jest nieco nie na temat. Problem polega na tym, że system przestaje reagować na długi czas, nawet jeśli swap jest wyłączony, a potem czasami nadal uruchamia program (więc gdzieś znajduje pamięć), a innym razem uruchamia oom_killer. System powinien być w stanie stwierdzić, że kończy się RAM, i po prostu nie pozwól mi uruchamiać więcej rzeczy. Czy jest więc jakiś sposób na zatrzymanie tych zawieszeń lub ustawienie tak wysokiego priorytetu wprowadzania danych przez użytkownika, że ​​mogę przełączyć się na konsolę, kiedy się zdarzają, i sam zabić niektóre procesy?
Krišjānis Nesenbergs
2

Od dłuższego czasu zmagam się z tym problemem, ale teraz wydaje się, że został rozwiązany na moim laptopie.

Jeśli żadna z pozostałych odpowiedzi nie działa dla ciebie (próbowałem większość z nich), graj z min_free_kbytes , aby mieć więcej miejsca w pamięci RAM, gdy komputer zacznie się zamieniać (tuż przed osiągnięciem tej minimalnej wartości na wolnej pamięci RAM).

Mam 16 GB pamięci RAM, ale wcześniej niż później pamięć zapełniła się, a następnie przestała odpowiadać przez 10 do 30 minut, aż niektóre rzeczy się podmieniły.

Przynajmniej dla mnie ustawienie wartości min_free_kbytes powyżej zalecanej powoduje, że proces zamiany jest znacznie szybszy.

W przypadku 16 GB pamięci RAM spróbuj tego:

vm.min_free_kbytes=500000

Aby ustawić tę wartość, zobacz inne odpowiedzi lub po prostu google :)

Beto Aveiga
źródło
0

Ciągle uruchamiam jeden z moich laptopów z karty SD Ubuntu na żywo, z małą partycją pamięci ext4 i plikiem wymiany na dysku twardym. Gdy używana jest prawie cała pamięć RAM, a wartość swapiness jest zbyt niska (czasami wolę całkowicie wyłączyć dysk twardy, jeśli to możliwe, ponieważ jest głośny), wydajność Linuksa spada dla mnie z klifu, tak że po prostu dostaję się do TTY1 zabicie Firefoksa zajmuje 15 minut.

/proc/sys/vm/vfs_cache_pressureWydaje się, że podniesienie wartości domyślnej 100 do wartości 6000 pomaga temu zapobiec. Jednak dokumentacja jądra ostrzega przed tym, mówiąc:

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.

Nie jestem do końca pewien skutków ubocznych, dlatego ostrożnie to robię.

Hitechcomputergeek
źródło
Prawdopodobnie uzyskasz lepsze wyniki przy wartościach vfs_cache_pressurezbliżonych do 10 (czyli znacznie mniejszych niż 100) i min_free_kbyteswyższych. Ostrzegamy, że jeśli ustawisz min_free_kbyteszbyt wysoko, zabójca jądra OOM zabije wszystkich!
Mikko Rantalainen,
@MikkoRantalainen Podniosłem już min_free_kbytesdo 262144 i zauważyłem, że obniżenie vfs_cache_pressurema odwrotny skutek - obniżenie go poniżej 100 powoduje, że system przestaje reagować znacznie szybciej. Nie jestem pewien dlaczego dokładnie.
Hitechcomputergeek,
Zasadniczo zwiększenie vfs_cache_pressurespowoduje, że katalogi zostaną wyrzucone przed zawartością pliku w pamięci podręcznej, w wyniku czego ogólna wydajność będzie zwykle spadać przy wartościach przekraczających 100. Jeśli uda Ci się wymyślić kroki do odtworzenia, aby zawiesić / zawiesić system, zaczynając od np. Ubuntu Live CD wtedy programiści jądra mogą ustalić przyczynę. Dla mnie zawieszenie następuje bez żadnego ostrzeżenia. Domyślam się, że jądro zawiesza się z powodu OOM, zanim OOM Killer zwolni wystarczającą ilość pamięci RAM. Używam teraz min_free_kbytes = 100000, admin_reserve_kbytes = 250000 i user_reserve_kbytes = 500000.
Mikko Rantalainen,
(ciąg dalszy) Nie zawiesiłem się z powyższą konfiguracją, mimo że mam swapiness = 5 i vfs_cache_pressure = 20. System ma 16 GB pamięci RAM i 8 GB wymiany na dysku SSD. Inny system ma 32 GB pamięci RAM i zerową zamianę i losowo wydaje się, że cierpi na ten sam problem - tam naciśnięcie Alt + SysRq + f po tym, jak system wydaje się być wolny, wydaje się pomocne, więc chyba OOM Killer działał wystarczająco szybko, system nie zawiesiłby się.
Mikko Rantalainen,