Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.17;
Скачать: CL | DM;

Вниз

утечка памяти   Найти похожие ветки 

 
misha123   (2004-09-24 16:56) [0]

Доброго дня.

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

Отрисовщик-обработчик листбокса:

procedure TForm1.ListBoxDrawItem;
var Offset: Integer;
   tb: boolean;
   s: string;
begin
with (Control as TListBox).Canvas do begin
  FillRect(Rect);
 if odSelected in State then begin
  Font.Color := clWhite;
  Font.Style := [fsBold];
 end;
  image:=TImage((Control as TListBox).Items.Objects[Index]);
  if image<>nil then begin
   Draw(Rect.Left + 2, Rect.Top, image.Picture.Graphic);
   Offset := image.width + 6;
   TextOut(Rect.Left + Offset, Rect.Top + image.Height div 2, (Control as TListBox).Items[Index] + "   &#185;" + inttostr(Index + 1));
  end;
end;
end;


Обработчик shelllistview:

procedure TForm1.stv_catalogClick(Sender: TObject);
var NodeName: string;
begin
NodeName:=stv_catalog.Selected.Text;

lb_listarticul.Clear;
cb_articuls.Clear;
image.Free;

NodeName:=path_catalog + NodeName + "\";
ShowItems(NodeName);


Формирование списка для отображения:

procedure TForm1.ShowItems;
var gifList: trGifList;
   i: integer;
   cursor: Tcursor;
begin
lb_listarticul.Cursor:=-11;
cb_articuls.Items.Clear;

gifList:=cProduct.FormFileListGif(NodeName);
 for i:=0 to length(giflist)-1 do begin
         image:=TImage.Create(form1);
         image.Picture.LoadFromFile(NodeName + giflist[i].namefile);
         delete(giflist[i].namefile, length(giflist[i].namefile)-3, 4);
         cb_articuls.Items.Add(giflist[i].namefile);
         lb_listarticul.Items.AddObject(giflist[i].namefile, image);
 end;
gifList:=nil;

lb_listarticul.Cursor:=0;
end;


image: TImage - объявлен глобально, при закрытии формы делается free.

gifList:=cProduct.FormFileListGif(NodeName); - формирует (в массиве; динамическом, но он в конце - nil) список файлов, лежащих в указанной папке.

Спасибо за возможные ответы :)


 
Iconka ©   (2004-09-24 17:03) [1]

Используй MemCheck. Узнаешь есть ли утечка или нет.
Что это - ищи в google - модуль.


 
Гаврила ©   (2004-09-24 17:04) [2]

Есть специальные тузлы, которые показывают место утечки.
ты кстати с чего взял, что она происходит ? Если по task manager" у - то не верь


 
Iconka ©   (2004-09-24 17:05) [3]


> с чего взял, что она происходит ?

Под системным блоком появилась небольшая лужа.
:)


 
Lin7   (2004-09-24 17:15) [4]

Есть хорошая утилита MemProof - находит утечки и показывает место в сырце. Была фришной.
Ищи на http://www.automatedqa.com


 
misha123   (2004-09-24 17:17) [5]

С чего я взял :) - в таск манагере - 6 (!) мб занимает программа, да и в росте не останавливается при очередном выборе ноды... Легко разрастается до 20-и и выше...

image:=TImage.Create(form1); - даже понятно где утечка. В цикле креат стоит. Но если я его за пределы выношу - все картинки отображаются как одна и та же.....


 
clickmaker ©   (2004-09-24 17:22) [6]


> [5] misha123   (24.09.04 17:17)
> image:=TImage.Create(form1); - даже понятно где утечка.
> В цикле креат стоит. Но если я его за пределы выношу - все
> картинки отображаются как одна и та же.....

Дык ты делай Free по необходимости


 
misha123   (2004-09-24 17:36) [7]

Ага я делаю, но image переменная глобальная - в обработчике события отрисовки листбокса тогда ничего отрисоваться не может - image-то nil. Варианты уже попробовал - если как локальные переменные объявлять image - утечка все-равно продолжается...

Вообще, странное какое-то поведение - один раз креат Image, а потом loadfromfile должен перегружать содержимое image

image.Picture.LoadFromFile(NodeName + giflist[i].namefile);

здесь имя файла меняется в цикле... но в список почему-то попадает одна и та же картинка....


 
clickmaker ©   (2004-09-24 17:39) [8]


> [7] misha123   (24.09.04 17:36)
> Ага я делаю, но image переменная глобальная
> здесь имя файла меняется в цикле... но в список почему-то попадает одна и та же картинка....

Именно потому что глобальная.
Ты же в цикле ее lb_listarticul.Items.AddObject(giflist[i].namefile, image);
Вот в обработчике оттуда и доставай.
А когда они станут не нужны - всех их Free


 
Basken   (2004-09-24 17:48) [9]

Создай контейнер TObjectList куда и запихивай картинки и при необходимости доставай их оттуда....

Images: TObjectList


 
misha123   (2004-09-24 18:07) [10]

to clickmaker :
Обработчик shelllistview: там как раз и стоит free - не помогает
А в обработчике листбокса они и так достаются....


 
clickmaker ©   (2004-09-24 18:14) [11]


> [10] misha123   (24.09.04 18:07)

Ты и правда не понимаешь? В обработчике shelllistview ты убиваешь ГЛОБАЛЬНУЮ переменную, а локальные в Objects остаются жить. И ты потом на их место пишешь новые


 
misha123   (2004-09-24 18:29) [12]

to Basken  - а чем плох listbox - точно так же хранит стринг и связанный с ним объект? Зачем я буду еще чего-то генерить?


 
Defunct ©   (2004-09-24 18:45) [13]

> image:=TImage.Create(form1);

Зачем это? И где вы убиваете все созданные Image?

Почему нельзя просто создать Bitmap?


 
misha123   (2004-09-28 13:13) [14]

to Defunct: в битмап нельзя, - использую гиф картинки...
в общем я почти разобрался - теперь пишу объекты в вектор, а потом по нему прохожусь и убиваю. Сильная утечка исчезла (понятное дело :) ). Теперь осталась слабая.
Что выяснил (использую tshelltreeview ): даже если комментирую вызов своей процедуры формирования списка и процедуры отрисовки листбокса (т.е. событие onclick для tshelltreeview остается, но в нем НИЧЕГО не происходит) - все-равно при щелчках по узлам потихоньку, но прога в памяти разрастается.
Что это? Глюк этого компонента?


 
Amoeba ©   (2004-09-28 13:33) [15]


> Сильная утечка исчезла (понятное дело :) ). Теперь осталась
> слабая.

А с помощью чего установлен этот факт? Если по показаниям TaskManager - то снова читай пост:
Гаврила ©   (24.09.04 17:04) [2]


 
zhe   (2004-09-28 17:21) [16]

убери строку
image:=TImage.Create(form1);

у тебя идёт накопление "бесхозных обьектов TImage в памяти". создай image ОДИН раз в начале рантайма. делай с ним всё, что хочешь. в конце рантайма просто FreeAndNil(image)


 
zhe   (2004-09-28 17:24) [17]

есть ещё вариант: сделать image локальным объектом и просто добывлять в список. на деструкторе списка освобождаешь все элементы коллекции картинок. так вроде даже лучше... насколько я допёр ситуацию


 
misha123   (2004-09-29 18:01) [18]

to zhe - если убрать - то в листбокс пишется указатель и соответственно когда в цикле я гружу в эту переменную новую картинку - указатели будут ссылаться все-время на новую картинку... - результат: список из всех одинаковых картинок (последняя загруженная картинка..).
Короче, с этим проблем нет - все уже сделал - ПРОБЛЕМА №2:

в обработчике onclick (где все и происходит) компонента TShellTreeView все комментирую, т.е. он вызывается но ничего не делает. Результат - смотрю в таскманагер - при каждом щелчке память потихоньку разрастается ~по 8 Кбайт. Т.е. я вообще выключил все написанное мной, а трабл остался...

to Amoeba: почему верить нельзя и чему тогда верить?

За ответы спасибо.


 
misha123   (2004-09-30 11:16) [19]

Еще ма-аленький вопрос... :)
потестировал программку на разных компах, выяснил: что на одной из машин (на остальных все в порядке) программа при закрытии не выгружается из памяти, форма закрывается, а в процессах программа остается. Причем уже вручную в обработчике formclose после дестроя всех моих объектов сказал  application.terminate - не помогает.

Это уже глюк ОС? Как с этим бороться?


 
Amoeba ©   (2004-09-30 15:49) [20]

В TaskManager, как уже об этом говорилось не раз, никогда не смотри - он тебе реальной картины не покажет - ну не способен он на это. Утечки памяти следует отлавливать ТОЛЬКО С ПОМОЩЬЮ специально предназначенных средств! Простейшее из них - MemCheck
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=944

Более слоное и мощное (причем тоже бесплатное) - MemProof


 
misha123   (2004-10-01 12:11) [21]

спасибо еще раз



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

Текущий архив: 2004.10.17;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.053 c
1-1096761465
Klopan
2004-10-03 03:57
2004.10.17
Поиск


3-1095410136
}|{yk
2004-09-17 12:35
2004.10.17
Это глюк Firebird?


1-1096864388
AlexV
2004-10-04 08:33
2004.10.17
Как из Delphi открыть страницу Internet в НОВОМ окне браузера?


6-1092303906
digger
2004-08-12 13:45
2004.10.17
idHTTP через прокси


4-1095323648
Alex_s
2004-09-16 12:34
2004.10.17
Реализация HOOK