Память может быть очищена?

Я работаю в Delphi 5 (с установленным FastMM) на проекте Win32 и недавно пытался решительно уменьшить использование памяти в этом приложении. До сих пор я сократил использование почти в половине, но заметил что-то при работе над отдельной задачей. Когда я минимизировал приложение, использование памяти, от которого уклоняются 45 megs вниз к 1 meg, который я приписал ему подкачку страниц к диску. Когда я восстановил его и перезапустил работу, память повысилась только к 15 megs. В то время как я продолжал работать, использование памяти медленно повышалось снова, и минимизирование и восстановление сбросили его, отступают к 15 megs. Таким образом к моим взглядам, когда мой код говорит системе освобождать память, за это все еще держатся согласно Windows, и фактическая сборка "мусора" не умирает до намного позже.

Кто-либо может подтвердить/отклонить этот вид поведения? Действительно ли возможно очистить память программно? Если бы я продолжаю использовать программу, не делая этого ручного сброса, я добираюсь из ошибки памяти через некоторое время и хотел бы устранить это.Спасибо.

Править: Я нашел статью о about.com, который дает многое из этого, а также некоторых ссылок и данных для других областей управления памятью.

30
задан Tom A 7 April 2010 в 22:44
поделиться

7 ответов

[

] Это то, что мы используем в []DSiWin32[]:[

] [
procedure DSiTrimWorkingSet;
var
  hProcess: THandle;
begin
  hProcess := OpenProcess(PROCESS_SET_QUOTA, false, GetCurrentProcessId);
  try
    SetProcessWorkingSetSize(hProcess, $FFFFFFFF, $FFFFFFFF);
  finally CloseHandle(hProcess); end;
end; { DSiTrimWorkingSet }
]
17
ответ дан 27 November 2019 в 23:06
поделиться
[

] Давайте разберемся: []FastMM4 не утечка памяти, ваш код может.[][

] [

]Чтобы быть уверенным, выполните эту инструкцию где-нибудь в вашем приложении (где FastMM4 находится в пункте use и []$define ManualLeakReportingControl[] установлен, в FastMM4Options. Inc, например):[

] [
ReportMemoryLeaksOnShutdown := True;
] [

]FastMM4 затем сообщит в конце, если вы забыли освободить немного памяти.[

] [

]Если вы хотите узнать немного больше, вы можете посмотреть []это видео с CodeRage 2: []Борьба с утечками памяти для манекенов [][][

]
5
ответ дан 27 November 2019 в 23:06
поделиться
[

] Task Manager не показывает общую сумму, выделенную приложением из Windows. Что он показывает (по умолчанию), так это рабочий набор. Рабочий набор - это концепция, которая предназначена для того, чтобы попытаться свести к минимуму перетаскивание файлов страниц в условиях ограниченной памяти. В основном это все страницы в памяти, к которым приложение регулярно прикасается, поэтому для того, чтобы приложение работало с приличной скоростью реакции, операционная система будет стараться держать рабочий набор в физической памяти.[

] [

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

] [

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

] [

]Таким образом, поведение, которое вы видите, это обрезка Windows рабочего набора при минимизации, а затем увеличение его резервного копирования с течением времени, по мере того, как приложение, восстановленное, касается все большего и большего количества страниц. Ничто не сравнится со сбором мусора.[

] [

]Если вас интересует использование памяти приложением под Windows, то здесь нет ни одного самого важного числа, а есть диапазон соответствующих чисел:[

] [
    ] [
  • ][

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

    ][
  • ] [
  • ][

    ][]Private working set[] - это страницы, которые являются приватными для данного приложения (т.е. не являются общими для нескольких запущенных приложений, так что изменение на одну из них видно всем), и являются частью рабочего множества (т.е. часто затрагиваются приложением).[

    ][
  • ] [
  • ][

    ][]Частный рабочий набор[] - это страницы в рабочем наборе, которые являются общими, но могут быть или не быть фактически общими. Например, DLL или пакеты (BPL) могут быть загружены в пространство памяти приложения. Код этих DLL потенциально может совместно использоваться несколькими процессами, но если DLL загружается только один раз в одно приложение, то на самом деле она не является совместно используемой. Если DLL очень специфична для этого приложения, то она функционально эквивалентна частному рабочему множеству.[

    ][
  • ] [
  • ][

    ][]Shared work set[] - это страницы из рабочего множества, которые фактически совместно используются. Можно представить себе, как "стоимость" этих страниц для любого приложения делится на количество совместно используемых приложений.[

    ][
  • ] [
  • ][

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

    ][
  • ] [
] [

]Эти числа не представляют собой разрозненные множества. Они представляют собой различные способы суммирования состояний различных типов страниц. Например, []рабочий набор [] = закрытый рабочий набор + разделяемый рабочий набор.[

] [

]Какое из этих чисел наиболее важно, зависит от того, чем вы ограничены. Если вы пытались выполнить ввод/вывод, используя файлы отображения памяти, виртуальный размер ограничит количество памяти, которое вы можете выделить для отображения. Если вы находитесь в окружении, ограниченном физической памятью, вы хотите минимизировать рабочий набор. Если у вас много разных экземпляров вашего приложения, работающих одновременно, вы хотите минимизировать приватные байты и максимизировать общие байты. Если вы создаёте кучу различных DLL и BPL, вы хотите быть уверены, что они на самом деле являются общими, убедившись, что их загрузочные адреса не приводят к их столкновению и предотвращают совместное использование.[

] [

][]О SetProcessWorkingSetSize:[][

] [

]Windows обычно работает с рабочим набором автоматически, в зависимости от давления на память. Рабочий набор не определяет, произойдет ли ошибка при нехватке памяти (OOM) или нет. Рабочий набор используется для принятия решений о пейджинге, т.е. что хранить в памяти и что оставить на диске (в случае DLL) или страницу на диск (другую зафиксированную память). Это не будет иметь никакого эффекта, если в системе не будет выделено больше виртуальной памяти, чем физической.[

] [

] Что касается эффекта: если нижняя граница [] установлена высоко [], это означает, что процесс будет враждебен другим приложениям, и будет пытаться "заглушить" память, в ситуациях физического давления на память. Это одна из причин, по которой требуется право на безопасность, PROCESS_SET_QUOTA.[

] [

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

] [

]В большинстве ситуаций, вы не хотите изменять детали рабочего набора. Обычно лучше позволить операционной системе справиться с этим. Это не предотвратит ситуации с OOM. Обычно они вызваны исчерпанием адресного пространства, потому что менеджер памяти не смог зафиксировать больше памяти; или в системах с недостаточным пространством файла страницы для резервирования выделенной виртуальной памяти, когда пространство в файле страницы заканчивается.[

].
73
ответ дан 27 November 2019 в 23:06
поделиться

Узнав от отличного ответа Барри Келли, попробуйте проанализировать свой процесс с помощью VMMap от Sysinternals, которую можно найти здесь . Он анализирует использование памяти отдельным процессом более подробно, чем Process Explorer: «VMMap - идеальный инструмент для разработчиков, желающих понять и оптимизировать использование ресурсов памяти своим приложением». У него также есть полезный справочный файл.

3
ответ дан 27 November 2019 в 23:06
поделиться

Я читал об этом раньше, но у меня нет прямого опыта. Вызов WINAPI SetProcessWorkingSetSize () должен «исправить» проблему. Опять же, у меня нет прямого опыта в этом.

0
ответ дан 27 November 2019 в 23:06
поделиться

Менеджер задач не показывает, что на самом деле использует ваша программа. Он показывает, что The Memory Manager выделил из Windows. Когда вы освободите объект или иным образом выделяете динамически выделенную память, он немедленно возвращается в Memory Manager (Fastmm). Независимо от того, передается ли это обратно к Windows - это другое дело. Memory Manager любит держать дополнительную память, сидящую вокруг, поэтому ему не нужно больше схватить от ОС каждый раз, когда вам нужно создать новый объект. (Это хорошо, и вы не хотите его менять.)

Если использование памяти вашей программы постоянно увеличивается, вместо того, чтобы ударить устойчивое состояние в какой-то момент, вы можете посмотреть и посмотреть, если вы вытекаете память где-то. И как упомянутая отметка, Delphi не использует автоматическую сборку мусора. На всякий случай, если вы не знаете об этом, убедитесь, что вы либо освобождаете свои объекты, либо передавая их собственность, что освободит их, когда они больше не нужны.

2
ответ дан 27 November 2019 в 23:06
поделиться

Недавно у меня была очень похожая проблема с моей программой. См. Мой вопрос: Почему память моей программы Delphi продолжает расти?

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

Прежде чем делать что-либо еще, убедитесь, что вы правильно высвобождаете всю свою память.

-1
ответ дан 27 November 2019 в 23:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: