В этом нет большой разницы между Windows и Unix.
В обоих есть два уровня распределения. Операционная система выделяет память процессу большими кусками (одна страница или более; в x86 размер страницы обычно составляет 4096 байт). Библиотеки времени выполнения, работающие внутри процесса, подразделяют это пространство и выделяют его части для вашего кода.
Чтобы вернуть память операционной системе, сначала вся память, выделенная из одного из этих больших кусков, должна быть освобождена для библиотеки времени выполнения. Затем библиотека времени выполнения может, если захочет, сообщить операционной системе освободить этот кусок памяти.
В Linux у вас есть brk
и mmap
. brk
контролирует размер большого куска памяти, выделенного вашему процессу; Вы можете расширить или уменьшить его, но только с одного конца. malloc
традиционно расширяет этот кусок памяти, когда ему нужно выделять больше памяти, и сокращает его, когда это возможно. Однако, сокращение не легкое; в конце требуется одно однобайтовое несвоевременное выделение, чтобы оно не могло сжиматься, даже если все до этого выделения было освобождено. Это источник мема «Unix не освобождает память».
Однако есть также аноним mmap
. Anonymous mmap
запрашивает часть памяти из операционной системы, которую можно разместить в любом месте пространства памяти процесса. Этот чанк можно легко вернуть, когда он больше не нужен, даже если есть более поздние выделения, которые еще не были освобождены. malloc
также использует mmap
(особенно для больших выделений, когда целый кусок памяти может быть легко возвращен после освобождения).
Конечно, и в Windows, и в Linux, если вам не нравится поведение распределителя памяти (или распределителей) из библиотек времени выполнения, вы можете использовать свой собственный, запрашивая память у операционной системы и подразделяя ее так, как вы хотите (или иногда запрашивая память у другого распределителя, но в больших блоках). Одним из интересных вариантов использования является наличие распределителя для всей памяти, связанной с задачей (например, запрос веб-сервера), который полностью отбрасывается в конце задачи (без необходимости освобождения всех частей по отдельности); Другое интересное использование - это распределитель для объектов фиксированного размера (например, пятибайтовых объектов), который позволяет избежать фрагментации памяти.