Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Вниз

Проблемы с диспетчером памяти..?   Найти похожие ветки 

 
arm79   (2004-08-05 18:14) [0]

Уважаемые мастера! Возникла неприятная ситуация с размерами занимаемой моей программой памяти. Работа идет с большим кол-вом списков и элементов в нем. Часто приходится удалять эти элемены и списки. На первый взгляд выделение и очистка памяти написаны корректно. Выдаваемые данные не искажаются, программа работает, функции выполняет. Но к концу дня "жрет" виртуальной памяти под гигабайт. В связи с этим вопрос, а высвобождаемое место при FreeMem повторно используется? Или виндовый диспетчер памяти не хочет увидеть кусочки такой памяти свободными? То есть я просто хочу знать, это моя прога однозначно виновата(в том плане, что я где то забываю освободить память) или есть вероятность, что диспетчер памяти в Win2000 некорректно работает? Программу приводить не буду, она слишком объемная, но если кто хочет, могу переслать по почте модуль, в котором идет работа со списками.
ЗЫ Удаляемые списки содержат указатели на целые числа. При удалении таких списков я сначала освобождаю память, на которую ссылаются элементы списка, потом вызываю метод Clear + FreeAndNil (или Free)


 
GuAV ©   (2004-08-05 19:24) [1]

System.AllocMemSize - внутренний счетчик памяти в Delphi


 
TUser ©   (2004-08-05 19:33) [2]


> высвобождаемое место при FreeMem повторно используется?
> Или виндовый диспетчер памяти не хочет увидеть кусочки такой
> памяти свободными? То есть я просто хочу знать, это моя
> прога однозначно виновата

Используется
Хочет
Однозначно

Вообще сочувствую - такие ошибки трудно находить, и на форуме обычно помочь ничем не могут - надо копать большое кол-во твоего кода. Только ты можешь исправить баг.


 
arm79   (2004-08-06 09:37) [3]

AllocMemSize - тоже прирастает.


 
Digitman ©   (2004-08-06 09:58) [4]

менеджер памяти Борланда, используемый по умолчанию в операциях с памятью в приложении (явные или неявные Get/Realloc/FreeMem), при необходимости запрашивает память из кучи процесса, причем запрашивает в объеме кратном странице (4к) и не отдает уже запрошенные страницы назад в кучу вплоть до завершения процесса из соображений повторного использования

если куча "тает на глазах", то это означает одно - затребованный к выделению объем памяти в запросах к BMM со стороны приложения явно превышает объем освобождаемой памяти в запросах к тому же ВММ, что делает возможным предположение об ошибках в логике приложения, ведущих к утечкам памяти


 
TUser ©   (2004-08-06 10:30) [5]

Digitman ©   (06.08.04 09:58) [4]
Правильно ли я вас понял, что освобожденная память может быть повторно использована моей программой, но никакой другой (до завершения процесса)?


 
Anatoly Podgoretsky ©   (2004-08-06 10:33) [6]

Ни до и ни после, твоя память не совпадает с память другого процесс, разное адресное пространство, в тоже время и адреса у вас одинаковые. В Виндоус вообще программы не занимают оперативную память, ее занимают страницы памяти, управляется системой. Ну это в общем.


 
TUser ©   (2004-08-06 10:47) [7]

Да, про это я слышал. Мне просо не очень понятна вот эта фраза

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

Т.е. получается, что FreeMem низаче не нужен, т.к. память все равно не может быть использована повторно, так что ли? В общем - непонятно.


 
Anatoly Podgoretsky ©   (2004-08-06 10:52) [8]

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


 
Digitman ©   (2004-08-06 11:06) [9]


> TUser ©   (06.08.04 10:47) [7]


куча - термин и механизм ОС
с каждым вновь стартующим процессом ОС по умолчанию ассоциирует одну индивидуальную кучу ... из этой кучи процесс вправе запрашивать блоки, которые ОС при успешном запросе отображает на страницы вирт.памяти АП процесса ... этим и занимается ВММ - получив от прикл.кода GetMem-запрос, он запрашивает из кучи одну или более страниц, структурирует их и уже из сформированных структур возвращает прикл.коду блок затребованной памяти ... когда прикл.код запрашивает у ВММ FreeMem, ВММ помечает в соотв.блок в своей структуре как свободный, но не отдает в кучу ранее запрошенные страничные блоки, чтобы при последующих GetMem можно было в своих   структурах быстро найти подходящий блок, вновь пометить его как занятый и тут же вернуть прикл.коду ... тем самым достигается минимизация обращений к куче


 
GuAV ©   (2004-08-06 12:39) [10]


> AllocMemSize - тоже прирастает.

А это уже однозначно ошибка в проге. AllocMemSize изменяется самам дельфи в GetMem.inc при всяких GetMem/FreeMem


 
Дуся   (2004-08-06 13:51) [11]

Вместе с arm79 проверяли, на первый взгляд - все getmem и create корректно потом освобождаются.. при этом подозрение вызывает только ОРГОМНОЕ их количество в коде... и то что выделяется по 4 байтика (на ИНТ)..
про страницы - очень интересно!.. может быть как раз и портит все такой маленький объем (4б)??


 
GuAV ©   (2004-08-06 14:02) [12]

Мне вот что интересно: на кой выделять 4 байта, если sizeof(pointer) = 4 ? Какой нибудь пример из этой самой проги можно?


 
Digitman ©   (2004-08-06 14:03) [13]

а в чем "прелесть" выделения 4-х байт обращением к ВММ ? с гораздо большим успехом и с неизмеримо меньшим геморроем можно и лок.переменную задать и использовать для такой цели


 
Дуся   (2004-08-06 14:34) [14]

Ну вот так вот сделали.. Динамические массивы индексов...


 
Дуся   (2004-08-06 14:38) [15]

вкратце - есть огромные динамические списки, есть списки с индексами для ускорения поиска, т.к. система критична по времени...

в процессе поиска формуруются временные списки с индексами найденных строк.
вот при их формировании-удалении и получается такая байда..


 
Digitman ©   (2004-08-06 14:45) [16]


> Дуся   (06.08.04 14:34) [14]
> Ну вот так вот сделали.. Динамические массивы индексов...


и оч криво сделали, imho

на то есть как минимум классы-наследники TList - они весьма эффективно и прозрачно управляются с памятью ... главное - следить за вызовом конструкторов/диструкторов


 
Дуся   (2004-08-06 14:47) [17]

т.е. вы думаете, что если мы, к примеру, возьмем TStringList и наши цифирки зафигачим не в объекты, а просто в строки, то будет нам счастье?


 
Digitman ©   (2004-08-06 14:53) [18]

уж не знаю насчет "счастья", но как минимум фрагментированность структур БММ можно ощутимо минимизировать ... и алгоритм существенно упростится, что даст возможность легче находить свои ошибки


 
Дуся   (2004-08-06 14:58) [19]

Спасибо. Этого я и боялась :)


 
TUser ©   (2004-08-06 15:54) [20]

2 [8] и [9]
Т.е. так и получается. У процесса есть своя куча, но память туда можно только забрать, но нельзя вернуть. Т.о. если процесс запустился в момент t0, то в момент t под него будет выделено памяти ровно максимальное количество, которое ему требовалось за все вемя работы. Даже если ему эта память не нужна, то получается, что другие поцессы не смогут ее использовать. Потому что при освобождении памяти она вернется в кучу, а ОС по-прежнему считает ее занятой. Так?

PS. Извиняюсь, что пытаюся разобраться с этим в чужой ветке.


 
Digitman ©   (2004-08-06 16:04) [21]


> Так?


не так


> У процесса есть своя куча


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

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


> память туда можно только забрать, но нельзя вернуть


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


Даже если ему эта память не нужна, то получается, что другие поцессы не смогут ее использовать


пока процесс существует - да, ресурсы, ассоциированные с блоками, не отданными в кучу, не могут быть использованными другими процессами


 
TUser ©   (2004-08-06 16:09) [22]

А если поцесс у меня работает много дней и ночей без перезапуска, то только одного FreeMem, получается, недостаточно, надо HeapFree? Кажется с начнаю понимать некоторые свои ошибки ...


 
Digitman ©   (2004-08-06 16:15) [23]


> TUser ©   (06.08.04 16:09) [22]


да не трогай ты хип ! не нужно тебе туда лезть ! ВММ сам разберется, когда и как с кучей работать... твое дело - при обращениях к ВММ соблюдать баланс между запросами блоков у него и соотв.отдачей ему этих блоков

если же баланс этот ты не соблюдаешь (т.е. суммарно запрошенная по GetMem память не соответствует суммарно оттданной по Freemem), то БММ будет вынужден запрашивать из кучи все новые и новые блоки, тем самым бестолково наращивая занимаемые у ОС твоим процессом  ресурсы


 
Digitman ©   (2004-08-06 16:21) [24]


> TUser


он (ВММ) поэтому и называется "менеджером памяти", потому что осуществляет посредничество между "поставщиком ресурсов" - кучей - и твоей прикладной задачей, нуждающейся не в каких-то там "кучах", а в гарантиях , что для хранения некоей инф-ции менеджер по ее запрпосу предоставил гарантированно существующий в ВАП процесса фиксированный диапазон адресов


 
Digitman ©   (2004-08-06 16:32) [25]


> TUser


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


 
GuAV ©   (2004-08-06 16:43) [26]

2 Дуся

> т.е. вы думаете, что если мы, к примеру, возьмем TStringList
> и наши цифирки зафигачим не в объекты, а просто в строки,
> то будет нам счастье?

имхо:
TList - если индексы по порядку. Items - интегеры typecast в pointerы
TBucketList из Unit Contnrs - если ассоцииировать Integer или Pointer с другим Integer или Pointer. опять же интегеры typecast в pointerы. TStringList не при чем.


 
Seldon ©   (2004-08-06 21:59) [27]


> пока процесс существует - да, ресурсы, ассоциированные с
> блоками, не отданными в кучу, не могут быть использованными
> другими процессами

А если моя программа в при старте загружает в TList ОГРОМНОЕ количество данных, работает с ними, потом освобождает память, занимаемую этими данными (TList.Clear;TList.Free) и в процессе дальнейшей работы не нуждается в таком ОГРОМНОМ количестве памяти, то вся память, выделенная при начальной обработке данных, будет недоступна другим процессам до окончания работы моей программы?


 
Дуся   (2004-08-09 14:31) [28]

Seldon ©
Признаться, я тоже хотела бы услышать четкий ответ на этот вопрос..


 
Digitman ©   (2004-08-09 14:35) [29]


> Seldon ©   (06.08.04 21:59) [27]


ты что-нибудь про механизм подкачки хоть краем уха слышал ? или для тебя это пустой звук ?


 
delphi2002 ©   (2004-08-09 17:37) [30]

>arm79
Пришли код.
Подивлюся.
Може знайду помилку :)
     delphi2002@ukr.net


 
Seldon ©   (2004-08-09 21:26) [31]


>  [29] Digitman ©   (09.08.04 14:35)
>
> > Seldon ©   (06.08.04 21:59) [27]
>
>
> ты что-нибудь про механизм подкачки хоть краем уха слышал
> ? или для тебя это пустой звук ?

Самым краешком.


 
Германн ©   (2004-08-10 03:51) [32]

2 Seldon ©   (06.08.04 21:59) [27]
> А если моя программа в при старте загружает в TList ОГРОМНОЕ количество данных...

Первый раз слышу, что в TList загружается "ОГРОМНОЕ количество данных". Обычно, в него загружается весьма небольшой список указателей. А уж сколько занимают памяти те структуры, на которые указывают элементы TList.Items - это уже другой вопрос! И (TList.Clear;TList.Free)  ни в коей мере не освобождают ее!


 
Дуся   (2004-08-10 10:57) [33]

Всем спасибо!!..
Убрали многочисленные GetMem/FreeMem
Сделали интегеры typecast в pointerы.

Результат - потери полностью прекратились!!
Делаем выводы.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.032 c
1-1091910730
NeVIP.
2004-08-08 00:32
2004.08.22
Номер элемента множества


1-1091688013
serg128
2004-08-05 10:40
2004.08.22
Как скопировать в буфер всю строку из Grid?


3-1090927751
Экспериментатор
2004-07-27 15:29
2004.08.22
Как правильно сортировать?


3-1090879863
bigfoot
2004-07-27 02:11
2004.08.22
Выборка по дате


1-1091793629
Sourse
2004-08-06 16:00
2004.08.22
Как перетаскивать файлы из проводника в программу





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский