Назад | Перейти на главную страницу

Подкачка активного процесса, несмотря на свободную память

По какой-то причине наша система начинает подкачку (активно используемой памяти) примерно с 60 ГБ используемой памяти. (см. правку ниже, кажется, что использование ввода-вывода и дискового кэша, даже для ранее запущенных процессов, имеет эффект) Отключение (swapoff-a) для тестирования приводит к bad_alloc один раз (я предполагаю, потому что в то время было больше процессов, также использующих память), но также работал над ускорением моей программы более чем в 10 раз.

Это воспроизводит проблему (без других важных процессов, выполняющих EDIT: см. Ниже, это происходит только в том случае, если незадолго до этого выполнялся интенсивный процесс ввода-вывода):

#include <cstdio>
#include <vector>

int main() {
  size_t bytes = size_t(80) * 1024 * 1024 * 1024; // 80GB
  size_t* data = new size_t[bytes / sizeof(size_t)];
  for (size_t i = 0; i < bytes / sizeof(size_t); ++i) {
    data[i] = i;
  }
  for (;;) {}
}

Приблизительно при 60 ГБ используемой памяти система начинает подкачку, и загрузка ЦП опускается ниже 100% (потому что сейчас процесс привязан к вводу-выводу, я думаю).

Система - Ubuntu 14.04, 64-битная:

Linux ... 3.13.0-77-generic #121-Ubuntu SMP Wed Jan 20 10:50:42 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Как только точка будет достигнута, вот что дает мне бесплатный -m:

              total        used        free      shared  buff/cache   available
Mem:          96671       55504         358          60       40808       40478
Swap:         47679       19366       28313

Проблема сохраняется с swappiness = 1 (если что-то с интенсивным вводом-выводом только что было запущено, и особенно для моего фактического виновника (не приведенного выше кода), который выполняет и то, и другое, много операций ввода-вывода и использует много памяти. Если было мало или нет Ввод-вывод в последнее время, программа выше выделяет всю память и не меняет местами!

Проблема исчезнет, ​​если в течение длительного времени не было ничего интенсивного ввода-вывода. Кажется, что ОС каким-то образом заставляет мое приложение менять местами, потому что считает дисковый кеш более ценным - даже при очень низком уровне подкачки. Я не понимаю этого поведения, потому что память дискового кеша должна быть такой же хорошей, как и свободная память, и, безусловно, не запускать подкачку в запущенном процессе.

Изначально моя проблема возникла в приложении, которое читает большие файлы и использует много памяти. Впоследствии он сохраняется в приведенном выше примере кода, в котором вообще нет ввода-вывода. Наконец, когда я позже запускаю пример кода, подкачки не происходит.

Проверьте vmstat чтобы увидеть si, so (swap in / out) фактически заполняет любой своп. даже если для swappiness установлено значение 0, swap может выделить swap.

64 ГБ кажется пределом для 32-битной Ubuntu с поддержкой PAE: https://help.ubuntu.com/community/32bit_and_64bit

32-разрядный компьютер имеет размер слова 32 бита, что теоретически ограничивает объем памяти до 4 ГБ. Этот барьер был расширен за счет использования «расширения физического адреса» (или PAE), которое увеличивает лимит до 64 ГБ, хотя доступ к памяти выше 4 ГБ будет немного медленнее.