Delphi: справочник по управлению виртуальной памятью FastMM? - PullRequest
4 голосов
/ 28 марта 2011

Недавно у меня возникла проблема (см. Мой последний вопрос), которая побудила меня поближе взглянуть на управление памятью в моем приложении Delphi. После моего первого исследования у меня есть два вопроса.

Я начал играть с FastMMUsageTracker и заметил следующее. Когда я открываю файл, который будет использоваться приложением (которое также создает форму и т. Д.), Существует существенное несоответствие между изменением доступной виртуальной памяти для приложения и изменением в памяти, выделенной FastMM4.

Во-первых, меня немного смущает терминология: почему существует некоторая память, выделенная FastMM, и некоторая память, выделенная системой (и зарезервированная)? Поскольку FastMM является диспетчером памяти, почему система отвечает за выделение части памяти?

Кроме того, как я могу получить более подробную информацию о том, какие объекты / структуры были выделены этой памяти? Диаграмма VM полезна только для отображения объема памяти, который «выделен системе», «зарезервирован системой» или «выделен FastMM», но нет ссылки на фактические объекты, требующие этой памяти. Можно ли, например, получить отчет в середине исполнения, подобный тому, который генерирует FastMM при закрытии приложения? FastMM, очевидно, хранит эту информацию где-то.


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

Спасибо!

PS: Речь идет не о поиске утечек, никаких проблем, просто попытка лучше понять управление памятью и быть упреждающей в будущем, поскольку наше приложение использует все больше и больше памяти.

Ответы [ 3 ]

3 голосов
/ 28 марта 2011

Некоторые из ваших вопросов просты.Ну, в любом случае, один из них!

Почему существует некоторая память, выделенная FastMM, и некоторая память, выделенная системой (и зарезервированная)?Поскольку FastMM является диспетчером памяти, почему система отвечает за выделение части памяти?

Код, который вы пишете в Delphi, является лишь частью того, что выполняется в вашем процессе.Вы используете сторонние библиотеки в форме DLL, особенно Windows API.Например, каждый раз, когда вы создаете форму Delphi, за ней находится множество объектов Windows, которые потребляют память.FastMM не выделяет эту память, и я предполагаю, что в вашем вопросе это называется «системным распределением».

Однако, если вы хотите углубиться, это очень быстро становится чрезвычайно сложной темой.Если вы хотите углубиться в реализацию управления памятью Windows, то я думаю, что вам нужно обратиться к серьезному справочному источнику.Я предлагаю Windows Internals Марка Руссиновича, Дэвида Соломона и Алекса Ионеску.

2 голосов
/ 28 марта 2011

Во-первых, меня немного смущает терминология: почему существует некоторая память, выделенная FastMM, и некоторая память, выделенная системой (и зарезервированная)?Поскольку FastMM является диспетчером памяти, почему система отвечает за выделение части памяти?

Как вы думаете, где FastMM получает память для выделения?Конечно, это происходит из системы.

Когда ваше приложение запускается, FastMM получает блок памяти из системы.Когда вы запрашиваете какую-то память для использования (будь то с GetMem, New или TSomething.Create), FastMM пытается передать ее вам из этого первого начального блока.Если там недостаточно, FastMM запрашивает больше (в одном блоке, если возможно) из системы и возвращает вам часть этого.Когда вы что-то освобождаете, FastMM не возвращает эту память в ОС, потому что полагает, что вы будете использовать ее снова.Он просто помечается как неиспользованный внутри.Он также пытается перераспределить неиспользуемые блоки так, чтобы они были как можно более смежными, чтобы не приходилось возвращаться к ОС более без необходимости.(Однако такая перестройка не всегда возможна; вот где вы в конечном итоге получаете фрагментацию памяти от таких вещей, как многократное изменение размера динамических массивов, создание и освобождение большого количества объектов и т. Д.)

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

Когда ваше приложение завершает работу, вся выделенная память высвобождается обратно в ОС.(Возможно, это не так сразу отображается в диспетчере задач, но это так.)

Можно ли, например, получить отчет в середине исполнения, аналогичный тому, что FastMM генерирует при закрытии приложения?

Не настолько, насколько я могу судить.Поскольку FastMM хранит его где-то, это не обязательно означает, что есть способ получить к нему доступ во время выполнения за пределами диспетчера памяти.Вы можете посмотреть на источник для FastMMUsageTracker, чтобы увидеть, как информация извлекается (используя GetMemoryManagerState и GetMemoryMap, в методе RefreshSnapshot).Источник для FastMM4 также доступен;вы можете посмотреть, какие общедоступные методы доступны.

Собственная документация FastMM (в виде файлов readme, комментариев FastMM4Options.inc и файла FastMM4_FAQ.txt) в некоторой степени полезна для объяснения того, какработает и какие варианты отладки (и информация) доступны.

0 голосов
/ 28 марта 2011

Для получения подробной карты памяти, используемой процессом, попробуйте VMMAP с www.sysinternals.com (также в соавторстве с Марком Руссиновичем, упомянутым в ответе Дэвида).Это также позволяет вам видеть, что хранится в некоторых местах (введите control-T, когда выделена линия детализации).

Предупреждение. Процесс использует гораздо больше памяти, чем вы думаете.Возможно, вам придется сначала прочитать книгу.

...