Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.04.2009, 00:11   #1
Oburec
Пользователь
 
Регистрация: 20.03.2009
Сообщений: 33
По умолчанию Освобождение памяти занимаемой объектом

вызываю деструктор класса, память не освобождается. У класса в полях записаны массивы данных (SetLength). Пишу тестовый пример, память освободждается, в основном приложении нет. Если кто сталкивался - намекните, хоть в какую сторону копать...
в отладчике попадаю в деструктор объекта, при этом ни байта не освобождается. делал setlength(0) на массивы внутри класса, хотя и так должно освобождать, все равно не помогает...

Последний раз редактировалось Oburec; 15.04.2009 в 01:07.
Oburec вне форума Ответить с цитированием
Старый 15.04.2009, 02:34   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

1)код в студию
2)чем память проверяешь?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 15.04.2009, 07:53   #3
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Как я понял из опыта, если есть еще память в системе свободная и не требуется другим приложениям, сервисам и т.п. то Windows (система) "физически" (через диспетчер задач) не освобождает память, а как бы удаляет те объекты, кучи и т.п. из того места в памяти. Зачем ? Да наверное чтобы если потом вы запросите из кучи несколько байт, то они уже будут в вашем распоряжении, поидеи это сделано для увеличения скорости работы приложения
Ну это я нигде не читал, просто работал с огромным кол-вом памяти и заметил такую зависимость.
p.s. особенно это заметно когда выделяются мегабайты памяти

Это все при том что ваш код идеален а вдруг вы там ошибочку сделали.
BOBAH13 вне форума Ответить с цитированием
Старый 15.04.2009, 08:30   #4
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от BOBAH13 Посмотреть сообщение
Как я понял из опыта, если есть еще память в системе свободная и не требуется другим приложениям, сервисам и т.п. то Windows (система) "физически" (через диспетчер задач) не освобождает память, а как бы удаляет те объекты, кучи и т.п. из того места в памяти. Зачем ? Да наверное чтобы если потом вы запросите из кучи несколько байт, то они уже будут в вашем распоряжении, поидеи это сделано для увеличения скорости работы приложения
совершенно верно.
Главные функции выделения памяти это функции VirtualAlloc/VirtualFree. Без них никуда. Но у них большая гранулярность выделения - 64 КБ. Для оптимизации выделения маленьких кусков памяти были созданы диспетчеры куч. Когда мы юзаем функции new/dispose, GetMem/FreeMem, SetLength и в конце концов API HeapAlloc/HeapFree мы обращаемся к разным диспетчерам куч. Они выделяют память с гранулярностью 8-16 байт. Принцип их работы прост: сначала выделяется большой кусок памяти, а потом маленькими кусочками он распределяется между потоками, подпрограммами и прочим.
Поэтому при освобождении памяти через dispose, FreeMem и другими потребление памяти программой не уменьшается.

Последний раз редактировалось rpy3uH; 15.04.2009 в 19:40.
rpy3uH вне форума Ответить с цитированием
Старый 15.04.2009, 21:22   #5
Oburec
Пользователь
 
Регистрация: 20.03.2009
Сообщений: 33
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
1)код в студию
2)чем память проверяешь?
есть самодельний 3д двиг, в процессе удаления объектов вызывается например такой деструктор
Код:
Destructor cMesh.Destroy;
begin
 setlength(VertexArray,0);
 setlength(NormalsArray,0);
 setlength(TexVertexArray,0);
 inherited;
end;
Это просто для примера. массивы вершин бывают довольно большими
Память выделяется как SetLength либо Create классов, которые хранятся в списках. Никаких других способов выделения памяти не применяется. Смотрю память в диспетчере задач, и еще так пытался:
Код:
function GetProcMem:cardinal;
var
  pmc: PPROCESS_MEMORY_COUNTERS;
  cb: Integer;
begin
  cb := SizeOf(_PROCESS_MEMORY_COUNTERS);
  GetMem(pmc, cb);
  pmc^.cb := cb;
  if GetProcessMemoryInfo(GetCurrentProcess, pmc, cb) then
    result:= pmc^.WorkingSetSize;
  FreeMem(pmc);
end;
В тестовых примерах все нормально освобождается, а в самом проекте фигня какая-то.
Цитата:
Сообщение от BOBAH13 Посмотреть сообщение
Как я понял из опыта, если есть еще память в системе свободная и не требуется другим приложениям, сервисам и т.п. то Windows (система) "физически" (через диспетчер задач) не освобождает память, а как бы удаляет те объекты, кучи и т.п. из того места в памяти...
Ну и как тогда вообще отлаживаться? Всмысле как проверить есть утечки или нет...

Последний раз редактировалось Oburec; 15.04.2009 в 21:25.
Oburec вне форума Ответить с цитированием
Старый 15.04.2009, 21:29   #6
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от Oburec Посмотреть сообщение
Ну и как тогда вообще отлаживаться? Всмысле как проверить есть утечки или нет...
если утечка есть, то это сразу понятно, программа начинает жрать много памяти.
rpy3uH вне форума Ответить с цитированием
Старый 15.04.2009, 21:32   #7
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Да, и то что я привел, это не есть утечка, это фича системы Windows. Так что не очем беспокоится, Вам, если и будут напряги система будет вынуждена "реально" отрезать от вас кусочек памяти
BOBAH13 вне форума Ответить с цитированием
Старый 15.04.2009, 22:21   #8
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от Oburec Посмотреть сообщение
Ну и как тогда вообще отлаживаться? Всмысле как проверить есть утечки или нет...
Для проверки можно использовать GetHeapStatus:

Код:
var BeginHeap, EndHeap : THeapStatus;
begin
    BeginHeap := GetHeapStatus;

    // операция

    EndHeap := GetHeapStatus;
    LostMemory := (EndHeap.TotalAllocated - BeginHeap.TotalAllocated);
Для большинства случаев это нормально работает. Неправильно учитывается автоматическое распределение (например, для строк), но такие места легко исключить из проверки.

Выключаем проверку:
SavedMemory := GetHeapStatus.TotalAllocated // запомнили текущее состояние

Включаем снова
CorrectMem += (GetHeapStatus.TotalAllocated - SavedMemory); // неучитываемая память

А в конце:
LostMemory := (EndHeap.TotalAllocated - BeginHeap.TotalAllocated) - CorrectMem;

Если это оформить в виде класса, получается удобный инструмент для отладки.
alexBlack вне форума Ответить с цитированием
Старый 16.04.2009, 08:24   #9
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от alexBlack Посмотреть сообщение
Для проверки можно использовать GetHeapStatus:
всё вроде бы хорошо и удобно. Но нельзя забывать что диспетчеры куч Delphi и C++ работают по своему, в обход функций Heap***. Не знаю как Delphi, но в С++ точно свой диспетчер куч (проверял на Visual C++ 6.0).

Последний раз редактировалось rpy3uH; 16.04.2009 в 08:26.
rpy3uH вне форума Ответить с цитированием
Старый 16.04.2009, 09:40   #10
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

В простейшем случае установить ReportMemoryLeaksOnShutdown = true, тогда программа при завершении скажет сколько байт не освободила и какой тип/класс виноват. В 7й делфе этого нет
пыщь
JTG вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Полиморфизм и выделение (освобождение) памяти Scogan Общие вопросы C/C++ 9 13.04.2009 07:57
Освобождение памяти AlexandrSid Общие вопросы Delphi 3 02.02.2009 13:45
Освобождение Памяти в Си volotsky Помощь студентам 2 16.12.2008 22:36
проблема с глобальным объектом Selebro Общие вопросы C/C++ 3 26.11.2008 20:22
Задача про работу с некоторым конструктивным объектом (напр. матрицей, графом, и т. д.) ACE Valery Помощь студентам 2 03.05.2008 19:22