ux31a зависает при нехватке памяти

У меня есть трудности с пониманием политики обмена. Я установил систему (Ubuntu 13.04, но 12.10 имел ту же проблему) с 4 ГБ раздела подкачки, потому что у ux31a есть 4 ГБ памяти.

Проблема заключается в том, что каждый раз, когда системе не хватает памяти и она начинает писать для замены, она перестает отвечать. Замораживает около 5 минут.

Итак, после некоторых чтений я подумал, что, возможно, мне следует установить swapiness на 10, и я сделал. После того, как система вышла из памяти - та же проблема.

Тогда я прочитал, что SSD не должен иметь никакого свопа, и я настроил отключить своп при запуске системы

Теперь у меня отключен своп, и мой free -m выглядит так:

             total       used       free     shared    buffers     cached
Mem:          3840       3340        499          0         33       1293
-/+ buffers/cache:       2013       1827
Swap:            0          0   
[ 116] К сожалению, проблема остается нерешенной. Похоже, буферы / кеш съедают всю память, и когда память становится равной 0, у меня точно такая же проблема. Я думал, что буферы / кэш должны автоматически освобождать часть памяти при необходимости, но я думаю, что это не

Что я могу сделать, чтобы избежать зависания системы?

дополнительная информация: когда система через некоторое время зависает он может отвечать на некоторые комментарии, и я смог получить доступ к консоли в другой сессии (Ctrl + Alt + F1) и запустить "top". Первые процессы kswapd0, kworkers съели весь процессор.

Заранее благодарю за помощь.

3
задан 7 May 2013 в 18:37

2 ответа

У меня также были проблемы с едой целой памяти. Похоже, это помогло, запустив с правами root:

echo N > /sys/module/drm_kms_helper/parameters/poll

В Интернете есть и другие посты об этом

0
ответ дан 7 May 2013 в 18:37

Я работаю без свопа, как и вы, и для того, чтобы предотвратить такие зависания ОС, я запускаю пользовательский патч ядра (также вставленный ниже, но вкладки стали пробелами), который работает для я, но, поскольку я не разработчик, я не могу гарантировать, что он не делает ничего другого, чего не следует делать.
Я запускаю пропатченное ядро ​​в dom0 и виртуальных машинах Qubes OS 4.0, применил его поверх ядер 4.18.9 и 4.19-rc5. Это легко проверить в виртуальных машинах Qubes, хотя dom0 sudo iotop может показать перегрузку диска (просто чтение, отсутствие записи), которая происходит, когда виртуальная машина зависла из-за почти нехватки памяти. Проблема в том, что он высвобождает кодовые страницы исполняемых файлов, поэтому их нужно перечитывать с диска при каждом переключении контекста .

Здесь - код, который может эмулировать высокое использование памяти, вы можете использовать его для тестирования. Короче говоря, что-то вроде этого:

$ stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 + 4000;}' < /proc/meminfo)k --vm-keep -m 4 --timeout 10s

Здесь - это исправление ядра, которое предотвращает любую зависание ОС и просто позволяет нормальному запуску oom-killer завершить процесс, который использует большинство ОЗУ (хотя в этой вставке вкладки заменены пробелами):

revision 3
preliminary patch to avoid disk thrashing (constant reading) under memory pressure before OOM-killer triggers
more info: https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 32699b2..7636498 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -208,7 +208,7 @@ enum lru_list {

 #define for_each_lru(lru) for (lru = 0; lru < NR_LRU_LISTS; lru++)

-#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_ACTIVE_FILE; lru++)
+#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_INACTIVE_FILE; lru++)

 static inline int is_file_lru(enum lru_list lru)
 {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 03822f8..1f3ffb5 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2086,9 +2086,9 @@ static unsigned long shrink_list(enum lr
                 struct scan_control *sc)
 {
    if (is_active_lru(lru)) {
-       if (inactive_list_is_low(lruvec, is_file_lru(lru),
-                    memcg, sc, true))
-           shrink_active_list(nr_to_scan, lruvec, sc, lru);
+       //if (inactive_list_is_low(lruvec, is_file_lru(lru),
+       //           memcg, sc, true))
+       //  shrink_active_list(nr_to_scan, lruvec, sc, lru);
        return 0;
    }

@@ -2234,7 +2234,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,

    anon  = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) +
        lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES);
-   file  = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
+   file  = //lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
        lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES);

    spin_lock_irq(&pgdat->lru_lock);
@@ -2345,7 +2345,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
             sc->priority == DEF_PRIORITY);

    blk_start_plug(&plug);
-   while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
+   while (nr[LRU_INACTIVE_ANON] || //nr[LRU_ACTIVE_FILE] ||
                    nr[LRU_INACTIVE_FILE]) {
        unsigned long nr_anon, nr_file, percentage;
        unsigned long nr_scanned;
@@ -2372,7 +2372,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
         * stop reclaiming one LRU and reduce the amount scanning
         * proportional to the original scan target.
         */
-       nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE];
+       nr_file = nr[LRU_INACTIVE_FILE] //+ nr[LRU_ACTIVE_FILE]
+           ;
        nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON];

        /*
@@ -2391,7 +2392,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
            percentage = nr_anon * 100 / scan_target;
        } else {
            unsigned long scan_target = targets[LRU_INACTIVE_FILE] +
-                       targets[LRU_ACTIVE_FILE] + 1;
+                       //targets[LRU_ACTIVE_FILE] + 
+                       1;
            lru = LRU_FILE;
            percentage = nr_file * 100 / scan_target;
        }
@@ -2409,10 +2411,12 @@ static void shrink_node_memcg(struct pgl
        nr[lru] = targets[lru] * (100 - percentage) / 100;
        nr[lru] -= min(nr[lru], nr_scanned);

+       if (LRU_FILE != lru) { //avoid this block for LRU_ACTIVE_FILE
        lru += LRU_ACTIVE;
        nr_scanned = targets[lru] - nr[lru];
        nr[lru] = targets[lru] * (100 - percentage) / 100;
        nr[lru] -= min(nr[lru], nr_scanned);
+       }

        scan_adjusted = true;
    }

ПРИМЕЧАНИЕ: я не рекомендую использовать это в производстве. Как я уже сказал, я не разработчик, и этот патч больше похож на доказательство концепции: он пытается не вытеснять из ОЗУ страницы Active(file), когда они находятся под высоким давлением памяти, и, таким образом, переключение контекста не должно повторяться. читать исполняемые файлы с диска во время их выполнения, таким образом, это не приведет к зависанию ОС из-за медленного повторного чтения этих исполняемых файлов с диска.

0
ответ дан 7 May 2013 в 18:37

Другие вопросы по тегам:

Похожие вопросы: