#c #memory #memory-leaks #tcmalloc
Вопрос:
У меня есть процесс, который потребляет много памяти при запуске, но освобождает большую часть этой памяти после загрузки процесса. Я вижу следующее в статистике TCMalloc, напечатанной впоследствии:
#012MALLOC: 16635888 ( 15.9 MiB) Bytes in use by application
#012MALLOC: 0 ( 0.0 MiB) Bytes in page heap freelist
#012MALLOC: 20007352 ( 19.1 MiB) Bytes in central cache freelist
#012MALLOC: 26367680 ( 25.1 MiB) Bytes in transfer cache freelist
#012MALLOC: 7030680 ( 6.7 MiB) Bytes in thread cache freelists
#012MALLOC: 1978560 ( 1.9 MiB) Bytes in malloc metadata
#012MALLOC: = 72020160 ( 68.7 MiB) Actual memory used (physical swap)
#012MALLOC: 239607808 ( 228.5 MiB) Bytes released to OS (aka unmapped). ***
#012MALLOC: = 311627968 ( 297.2 MiB) Virtual address space used
Здесь мы видим, что в ОС «выпущено ~228 МБ», но это также показывает, что это все еще часть виртуального адресного пространства процесса. Это подтверждается тем фактом, что показатель VSZ, наблюдаемый с помощью ps aux, остается высоким после просмотра этого журнала.
Когда я запускаю ту же программу со strace, я вижу, что: все вызовы brk увеличиваются, и что вызовы munmap (с точки зрения размеров) не суммируются с суммами, указанными в mmap (и показанными выше). Что еще хуже, так это то, что VSZ медленно увеличивается с течением времени, поскольку мой процесс выполняет фоновую работу, и регистрация показывает, что (***) соответственно увеличивается, когда регистрируются эти статистические данные.
Поэтому мои вопросы таковы: что представляет собой эта ценность? Освободилась моя память или нет? Что я могу сделать, чтобы предотвратить рост этого потребления?
Комментарии:
1. Возможно, записи TLB сохранены, но перенесены, предположительно, на нулевую страницу. Есть ли у вашей страйс какие-либо звонки
mremap()
?2. @Фрэнк, Нет, это не так.
Ответ №1:
Что представляет собой это значение?
Он представляет объем памяти, который TCMalloc сообщил системе, что он ей не нужен и который система может использовать для других целей.
Освободилась моя память или нет?
Нет. Операционная система решила, что делать ее бесплатной только для того, чтобы снова использовать ее, когда она нужна программе,-пустая трата усилий, и вместо этого решила переключить ее непосредственно с одного использования на другое за один шаг, вместо того чтобы тратить вдвое больше усилий на то, чтобы сделать ее бесплатной только для того, чтобы сделать ее несвободной для ее использования.
Что я могу сделать, чтобы предотвратить рост этого потребления?
Зачем тебе это нужно? Это просто облегчает задачу, если программе потребуется память позже, сводит к минимуму конфликты в свободном списке системы и вообще не оказывает вредного воздействия. TCMalloc сообщил ОС (через madvise(DONTNEED)
), что ОС может восстановить память, и ОС приняла решение, что не стоит освобождать ее только для того, чтобы использовать ее снова, когда это необходимо. У вас есть какие-то веские основания полагать, что операционная система неверна?
Гораздо проще просто напрямую перенести память из одного места в другое за один шаг, чем пройти два шага, чтобы освободить ее только для того, чтобы снова использовать. Бесплатный список может быть заблокирован под нагрузкой, и гораздо проще его не использовать.
Вы можете заставить ОС освободить ее, запустив какую-нибудь программу, которая потребляет много памяти, а затем завершается. Это заставит ОС перенести память в этот процесс, а затем освободить ее, когда этот процесс завершится. Но это не принесло бы никакой пользы и потребовало бы больших усилий только для того, чтобы в конечном итоге увеличить конкуренцию в диспетчере памяти. Здесь нет никаких проблем.
Комментарии:
1. Но почему это воспоминание не используется повторно? Со временем я могу наблюдать, как растет значение «Байты, выпущенные в ОС (они же не сопоставлены)». Почему процесс получает новую память из ОС вместо повторного использования того, что он ранее сообщил ОС, что ему больше не нужно?
2. @Nizbel99 Операционная система изо всех сил старается использовать как можно больше памяти. Свободная память не влияет на производительность и требует больше усилий для использования, чем уже используемая память. Операционная система идет по наиболее эффективному пути. Если позже процессу потребуется больше памяти, то чем больше ее уже выделила ОС, тем лучше. Практически в любом другом сценарии это либо связь, либо все же лучше не делать память свободной, а затем снова несвободной. Как вы думаете, какая польза будет от освобождения памяти?
3. Спасибо вам за объяснение. Поскольку память на самом деле не освобождается, означает ли это, что это утечка памяти?
4. @Nizbel99 Это зависит от того, что вы подразумеваете под «памятью». Если вы имеете в виду используемую физическую память, то нет, ОС по-прежнему правильно отслеживает ее и может повторно использовать. Если вы имеете в виду используемое адресное пространство процесса, то опять же нет, процесс по-прежнему правильно отслеживает его и может повторно использовать. Это все работает идеально, как задумано. Давление на память процесса приведет к повторному использованию адресного пространства. Нехватка системной памяти приведет к повторному использованию оперативной памяти. Это максимальная эффективность, а не выполнение ненужной работы, которую, возможно, придется просто отменить позже.