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

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.036 c
1-1096363145
msguns
2004-09-28 13:19
2004.10.17
Сообщение от одной форме другой


1-1096886393
Muchacho
2004-10-04 14:39
2004.10.17
Транслит


14-1096088459
Kair()
2004-09-25 09:00
2004.10.17


14-1096438790
msguns
2004-09-29 10:19
2004.10.17
Динамо (К) - Байер 4:2 !!!


14-1096185347
Rouse_
2004-09-26 11:55
2004.10.17
Конвертер дайджестов форумов в HTML формат





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский