Я смотрел на Boehm GC (для C/C++), и мне кажется, что (в Windows, но, вероятно, и в Linux) GC по умолчанию никогда не освобождает запрошенную память. Стоит отметить, что я использую более старую версию Boehm GC (7.6).
Кажется, часть, которая занимается распределением памяти, находится в os_dep.c, в Windows похоже, что память выделяется через VirtualAlloc. Я вижу, что сборщик мусора блокирует память в GC_win32_get_mem при создании новых объектов. Чтобы вернуть эту память, потребуется вызов VirtualFree, но, похоже, этого никогда не происходит (есть функция GC_win32_free_heap, но, похоже, она используется только некоторыми тестовыми наборами GC libs).
Есть флаг cmake — USE_MUNMAP. Из документации видно, что при использовании этого флага сборщик мусора иногда возвращает часть выделенной им памяти. Здесь я вижу, что VirtualFree вызывается из части кода, который находится внутри #ifdef в os_dep.c, и, собирая этот флаг, я могу его отладить и увидеть, что теперь он иногда вызывает VirtualFree.
Правильно ли я понимаю, что по умолчанию GC Boehm не освобождает выделенную память? Кто-нибудь знает больше о флаге «USE_MUNMAP» - единственное отличие использования этого флага заключается в том, что сборщик мусора (в определенных случаях, когда некоторые критерии соответствуют) возвращает выделенную память, или есть что-то еще? Также было бы интересно узнать, был ли этот дизайн выбран из соображений производительности. Я могу себе представить, что вызов VirtualFree приведет к некоторым издержкам производительности и, возможно, к фрагментации памяти? Это причина, по которой по умолчанию он вообще не возвращает память, или есть какая-то другая причина?
Если кто-нибудь может пролить свет на это, я был бы очень благодарен.
(Отредактировано 3 июля 2024 г., ранее в этом посте я уже упоминал об ОС, что, вероятно, вызвало некоторую путаницу. Меня интересует только то, выполняет ли Boehm GC соответствующий свободный вызов памяти, которую он ранее выделил, когда ее больше нет. использовать.)
Большинство распределителей памяти не освобождают память обратно в операционную систему. Если вы выделяете, а затем освобождаете достаточно большие фрагменты памяти, они могут быть полностью освобождены, но чаще всего память сохраняется на случай, если она понадобится вам позже.
Даже если бы он захотел вернуть память, он смог бы сделать это только в том случае, если бы вся страница памяти, отображенной в mmap, стала мусором. Вы не можете вернуть меньшие блоки памяти.
Я отредактировал вопрос, сказав, что «возврат памяти в ОС» на самом деле не то, что я имел в виду. Я имел в виду выполнение соответствующего бесплатного вызова внутри программы, когда выделенная область памяти больше не используется сборщиком мусора.
BDWGC v8.0.0 (и более поздние версии) по умолчанию возвращает неиспользуемую память ОС (на большинстве целевых платформ). Для более старых версий BDWGC вы можете передать флаг --enable-munmap
для настройки включения этой функции.
Привет Иван и спасибо за ответ. Я не вижу никакого «--enable-memory-unmapping», но в файле configure.ac есть «--enable-munmap». Я предполагаю, что munmap — это просто сокращение от unmapping памяти. Это тот, о котором вы говорите?
Опечатка в названии опции, исправил
Я не голосую за дубликат, потому что реализация Boehm GC отличается от стандартной C
malloc
/free
, но ответ на этот вопрос обсудим, что память, освобожденная в куче, не возвращается в ОС, это нормально. .