Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Утечка памяти при прокрутке картинок в Grid  (Прочитано 26807 раз)
0 Пользователей и 12 Гостей смотрят эту тему.
Levka
Гость
« : 17-09-2003 07:36 » 

Прошу помочь со следующей проблемой.
Я сделал простенький просмотрщик картинок (изображения формата JPEG, Win98, d5). Изображения (масштабированные) помещаются в

Grid (однострочный). При простой прокрутке грида происходит непонятная мне катастрофическая утечка физической памяти.

Технология такая: в OnCreate формы картинки загружаются в Objects ячеек грида:
Код:

...
var
 j    {integer;
 pct  {tpicture;
...
 with stringrid1 do
 for j{=0 to colcount-1 do
 begin
    pct{=tpicture.create;
    pct.loadfromfile)fname[j(:; //fname[j( - массив с именами файлов
    objects[j,0({=tobject)pct:;
 end;
...

В процедуре для события OnDrawCell сетки картинки рисуются:
Код:

...
with sender as StringGrid do
  if )acol>=0: and )arow>=0: then
  begin
    rect{=scaling)tpicture)objects[acol,0(:,rect:;
|scaling - функция для пропорционального масштабирования изображения по размерам ячейки сетки,
дело явно не в ней - когда я ее отключаю, результат тот же"
    canvas.strechdraw)rect,tpicture)objects[acol,0(.graphic:
  end;
...

С чем может быть связано утекание памяти и как с ним бороться?
Записан
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 17-09-2003 08:20 » 

Я не работаю с делфи но могу предположить что вот эта конструкция
tpicture(objects[acol,0].graphic)
создает новый объект tpicture.
С точки зрения OOП такая операция законна и объект класса должен быть разрущен после вызова.
Но графические объекты немного в этом плане отличаются,  tpicture  это не сам графический объект а только обертка вокруг ХЕНДЕЛА с доп функциями и разрушение ее не влечет за собой уничтожение самого объекта. Покрайней мере так это выглядит со стороны API.

Возможно в этом и проблема   tpicture(objects[acol,0].graphic) ты плодишь картинки.
Записан

Да да нет нет все остальное от лукавого.
Anonymous
Гость
« Ответ #2 : 17-09-2003 10:49 » 

2PSD:
Очень может быть, что ты прав:
Цитата

Возможно в этом и проблема tpicture(objects[acol,0].graphic) ты плодишь картинки

НО что можно предложить, чтобы это обойти?
Записан
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 17-09-2003 11:07 » 

почему нельзя напсать так
canvas.strechdraw(rect,objects[acol,0].graphic)
или
так
canvas.strechdraw(rect,objects[acol,0])

У меня нет подруками дельфей и яне могу прсмореть возвращаемые методами типы.
Записан

Да да нет нет все остальное от лукавого.
Aleck D.Shadow
Опытный

tr
Offline Offline
Пол: Мужской

« Ответ #4 : 17-09-2003 11:53 » 

Попробуй очищать канвас перед прорисовкой очередного изображения.
Записан
Levka
Гость
« Ответ #5 : 17-09-2003 13:03 » 

2 PSD:
Цитата

почему нельзя напсать так
canvas.strechdraw(rect,objects[acol,0].graphic)

потому что strechdraw нужон Tgraphic, а objects - TObject
2 Aleck D.Shadow
sorry, а как мне на сетке очистить нужный кусок холста - rect?
Записан
Levka
Гость
« Ответ #6 : 17-09-2003 13:12 » 

2 PSD:
Цитата

почему нельзя напсать так
canvas.strechdraw(rect,objects[acol,0].graphic)

потому что strechdraw нужон Tgraphic, а objects - TObject
2 Aleck D.Shadow
sorry, а как мне на сетке очистить нужный кусок холста - rect?
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #7 : 18-09-2003 05:24 » 

в OnCreate ты создаёшь объект - TPicture. потом присваиваешь его в Objects. а где ты это всё освобождаешь? класс StringGrid не является владельцем Objects, они продолжают существовать даже после того, как уничтожается StringGrid (см. F1: Note:   The string grid does not own the objects in the Objects array. Objects added to the Objects array still exist even if the string grid is destroyed. They must be explicitly destroyed by the application.). т.е. требуется в OnDestroy формы прописать освобождение всех твоих Objects из StringGrid'a, и всё будет хорошо.

З.Ы. А для того, что очистить нужный кусок холста, делаешь
Код:

  with SrtingGrid1.Canvas do
    begin
      Brush.Color {= Color;
      Pen.Color {= Color;
      FillRect )Rect:;
    end;
Записан

sss
Специалист

ru
Offline Offline

« Ответ #8 : 18-09-2003 06:13 » 

Цитата: PSD
могу предположить что вот эта конструкция
tpicture(objects[acol,0].graphic)
создает новый объект tpicture.


сто пудово не создает. Просто приведение типов. Мне кажется что замес происходит только с JPEG файлами. Там в зависимости от типов, разные классы используются. Рисуй не классом Canvas, а используй контексты HDC.
Или смотри по исходникам. Год назад я с этим сталкивался. Через некоторое время погляжу как делал ...
Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #9 : 18-09-2003 06:23 » 

Да нет. Все так же

Код:


procedure TImageViewPanel.PaintImage;
 var
    X, Y{ Integer;
    F{ Boolean;
begin
 if not Empty then
   begin
    if Picture.Graphic is TMetafile then
     begin
      Canvas.Brush.Style {= bsSolid;
      Canvas.Brush.Color {= Color;
      Canvas.Rectangle)ClientRect:;
     end;
      F {= FStretch;
      if FPicture.Graphic is TIcon then FStretch {= False;
      case FStretch of
       False{ begin
               if FRulesX then X {= FOriginX
                          else X {= )ClientWidth - FPicture.Width: div 2;
               if FRulesY then Y {= FOriginY
                          else Y {= )ClientHeight - FPicture.Height: div 2;
               Canvas.Draw)X, Y, FPicture.Graphic:;
              end;
        True{ Canvas.StretchDraw)Rect)0, 0, ClientWidth, ClientHeight:, FPicture.Graphic:;
       end;
      FStretch {= F;
   end;
end;

Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #10 : 18-09-2003 06:29 » new

Ни хрена себе я прогнал ....
 Я шокирован! Базар вообще не о том
Поглупел в армии
Записан

while (8==8)
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #11 : 18-09-2003 06:38 » 

2 sss: использование контекстов, кстати, ничего не даст. если ты будешь дёргать контекст по-честному, через GetDC, ты получишь всё тот же StringGrid1.Canvas.Handle (hDC), только тебе придётся ещё и освобождать свой экземпляр DC. а работа через сам Canvas.Handle смысла не несёт, потому что методы TCanvas сводятся к вызову тех же api-шных функций с передачей им Canvas.Handle в качестве DC.
Записан

sss
Специалист

ru
Offline Offline

« Ответ #12 : 18-09-2003 06:50 » 

x77, я все понял. Я в проблему не врубился просто. Думал не рисуется, а тут утечка.
Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #13 : 18-09-2003 07:01 » 

Levka, как утечку выявляешь ?
Записан

while (8==8)
Aleck D.Shadow
Опытный

tr
Offline Offline
Пол: Мужской

« Ответ #14 : 18-09-2003 09:18 » 

Цитата

sorry, а как мне на сетке очистить нужный кусок холста - rect?

Это ни к чему не  приведет. Дело в том что изначально холст(canvas)
равен 0, после того как ты нарисуешь что либо на canvase соответственно размер увиличивается, но стерев какой-то определенный участок ничего не даст.
Нужно всё стирать и рисовать только видимую часть.
Записан
Levka
Гость
« Ответ #15 : 18-09-2003 09:23 » 

Утечку определяю достаточно просто - перед запуском моей программы запускаю простеньку программу, в которой раз в секунду происходит обращение к функции GlobalMemoryStatus и ее член (или как там это называется) dwAvailPhys показывет в заголовке формы (т.е. на панели задач) количество доступной физ. памяти
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #16 : 18-09-2003 09:33 » 

Levka, ещё раз, освобождай все свои объекты (Objects) и не будет никаких утечек.

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

Levka
Гость
« Ответ #17 : 18-09-2003 09:52 » 

2 Младенец
Разумеется, я освобождаю objects перед выходом из программы - но ведь у меня ведь утечка наблюдается не после выхода из программы, а в процессе простой прокрутки сетки. Твое предложение о заливке канвы цветом, увы, ничего не дало - все та же утечка памяти. Так что вопрос по-прежнему стоит на том же месте.
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #18 : 18-09-2003 09:57 » 

блин, я просто ответил, на вопрос, как очистить холст, к утечке оно никакого отношения не имеет. да и вообще холст здесь не при чём, его handle в любом случае освобождается самим stringgrid'ом.

приведи полностью текст OnDrawCell, pls.
Записан

Anonymous
Гость
« Ответ #19 : 18-09-2003 12:17 » 

Попробуй сделать кнопку по которой канвас будет стираться(Clear). Покрути скроллером, затем нажми на кнопку и посмотри результат.
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #20 : 18-09-2003 12:28 » 

да по-моему, бред это всё. только что сделал пустую форму, кинул грид, RowCount = 1000, в OnCreate получаю значение PhysAvail, в OnSelectSell вывожу текущее. оно скачет, как хочет - и уменьшается, и увеличивается, но в основном - уменьшается. хотя я ВООБЩЕ ничего нигде не рисую и не вывожу, просто листаю грид.

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

Levka
Гость
« Ответ #21 : 18-09-2003 13:27 » 

2 Младенец
Бред- не бред, но я ведь не от нечего делать стал определять утечки памяти - дело в том, что после некоторого времени работы с набором картинок (точнее, их простой прокрутки), особенно из IDE дельфи, система зависает. Кстати, у меня создалось впечатление, что  MemoryStatus работает вполне прилично - после выхода из программы объем памяти восстанавливается. Должен сказать, что если количество картинок невелико и помещается в отображаемое на экране количество ячеек сетки, утечки нет - т.е. по-моему прблема в OnDrawCell
Записан
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #22 : 18-09-2003 13:30 » 

тогда приведи её текст полностью, плз.
Записан

x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #23 : 18-09-2003 13:33 » 

если после выходя из программы объём памяти восстанавливается - то это тоже значит, что утечек нет. то, что в процессе работы меняется объём доступной апмяти - это вполне есстественно.
Записан

Var-Alex
Гость
« Ответ #24 : 19-09-2003 09:58 » 

Цитата: x77
если после выходя из программы объём памяти восстанавливается - то это тоже значит, что утечек нет. то, что в процессе работы меняется объём доступной апмяти - это вполне есстественно.

Мне кажется это не совсем верно. Могут быть утечки памяти, которая освободиться после закрытия программы. В NT системах, при убиении процесса ВСЯ помять освобождается (ну кроме специальных типов типа расшаренной). А если в процессе работы есть утечка памяти, то постепенно, программа может занять ВСЮ доступную память, и склинить при попытке выделить новый необходимый кусок. Думаю для программ типа просмоторщика картинок это не критично, а вообще ....
Записан
Var-Alex
Гость
« Ответ #25 : 19-09-2003 10:00 » 

Цитата: Levka
Утечку определяю достаточно просто - перед запуском моей программы запускаю простеньку программу, в которой раз в секунду происходит обращение к функции GlobalMemoryStatus и ее член (или как там это называется) dwAvailPhys показывет в заголовке формы (т.е. на панели задач) количество доступной физ. памяти


Не занимайся хренью. Скачай memProof и ищи не убитые объекты и прочие утечки ею. Адрес точно не скажу, в яндексе найдешь на ура.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines