Файлы, отображаемые в памяти Linux, резервируют много физической памяти - PullRequest
5 голосов
/ 24 сентября 2010

У меня есть проблема, которая была описана в нескольких потоках относительно отображения памяти и растущего потребления памяти под Linux.

Когда я открываю файл объемом 1 ГБ в Linux или MacOS X и отображаю его в память, используя

me.data_begin = mmap(NULL, capacity(me), prot, MAP_SHARED, me.file.handle, 0);

и последовательно считывая сопоставленную память, моя программа использует все больше физической памяти, хотя я использовал posix_madvise (даже вызывал ее несколько раз в процессе чтения):

posix_madvise(me.data_begin, capacity(me), MMAP_SEQUENTIAL);

без успеха. : - (

Я пытался:

  • разные флаги MMAP_RANDOM, MMAP_DONTNEED, MMAP_NORMAL без успеха
  • posix_fadvise (me.file.handle, 0, емкость (я), POSIX_FADV_DONTNEED) до и после вызова mmap -> безуспешно

Это работает под Mac OS X !!! когда я объединяю

posix_madvise(.. MMAP_SEQUENTIAL)

и

msync(me.data_begin, capacity(me), MS_INVALIDATE).

Резидентная память меньше 16M (я периодически вызывал msync после 16 миллионов шагов).

Но под Linux ничего не работает . У кого-нибудь есть идея или история успеха для моей проблемы под Linux?

Ура, David

1 Ответ

8 голосов
/ 25 сентября 2010

Управление памятью в Linux отличается от других систем.Ключевой принцип заключается в том, что память, которая не используется, является потерей памяти.Во многих отношениях Linux пытается максимизировать использование памяти, что приводит (в большинстве случаев) к повышению производительности.

Дело не в том, что " ничто не работает " в Linux, но его поведениенемного отличается от того, что вы ожидаете.

Когда страницы памяти извлекаются из файла mmapped, операционная система должна решить, какие страницы физической памяти она освободит (или выгрузит) для использования.Он будет искать страницы, которые легче поменять (не требующие немедленной записи на диск) и которые с меньшей вероятностью будут использоваться снова.

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

Чтобы продемонстрировать влияние madvice () на Linux, я изменил одно из упражнений, которое я даю своим студентам.Смотрите полный исходный код здесь .Моя система 64-битная и имеет 2 ГБ оперативной памяти, которая сейчас используется примерно на 50%.Используя программу для отображения файла размером 2 ГБ, прочитайте его последовательно и откажитесь от всего.Он сообщает об использовании RSS каждые 200 МБ.Результаты без madvice () :

<juliano@home> ~% ./madvtest file.dat n
     0 :     3 MB
   200 :   202 MB
   400 :   402 MB
   600 :   602 MB
   800 :   802 MB
  1000 :  1002 MB
  1200 :  1066 MB
  1400 :  1068 MB
  1600 :  1078 MB
  1800 :  1113 MB
  2000 :  1113 MB

Linux продолжал выталкивать вещи из памяти, пока не было прочитано около 1 ГБ.После этого он начал давить на сам процесс (так как остальные 50% памяти были активны другими процессами) и стабилизировался до конца файла.

Теперь с madvice () :

<juliano@home> ~% ./madvtest file.dat y
     0 :     3 MB
   200 :   202 MB
   400 :   402 MB
   600 :   494 MB
   800 :   501 MB
  1000 :   518 MB
  1200 :   530 MB
  1400 :   530 MB
  1600 :   530 MB
  1800 :   595 MB
  2000 :   788 MB

Обратите внимание, что Linux решила выделить страницы процессу только до тех пор, пока он не достигнет 500 МБ, гораздо раньше, чем без madvice ().Это потому, что после этого страницы, находящиеся в данный момент в памяти, казались гораздо более ценными, чем страницы, которые были помечены как последовательный доступ этим процессом.В VMM существует пороговое значение, определяющее, когда начинать удаление старых страниц из процесса.

Вы можете спросить, почему Linux продолжал выделять страницы размером до 500 МБ и не останавливался намного раньше, поскольку они были помеченыкак последовательный доступ.Дело в том, что либо в системе было достаточно страниц свободной памяти, либо другие резидентные страницы были слишком старыми, чтобы их можно было хранить.Между хранением древних страниц в памяти, которые больше не кажутся полезными, и предоставлением большего количества страниц для обслуживания программы, работающей сейчас , Linux выбирает второй вариант.

Даже если онибыли помечены как последовательный доступ, это был просто совет.Приложение может по-прежнему хотеть вернуться к этим страницам и прочитать их снова.Или другое приложение в системе.Вызов madvice () говорит только о том, что делает само приложение, Linux учитывает общую картину.

...