Конференция "KOL" » Утечка GDI-ресурсов [Delphi, Windows]
 
  • G-Host © (05.01.12 17:36) [0]
    Есть форма, на ней - TKOLListView
    В момент создания формы в function TControl.CreateWindow: Boolean; вызывается
    fHandle := CreateWindowEx( Params.ExStyle, Params.WinClassName,..., который создает окно класса obj_SysListView32. При этом создаются 1 BRUSH и 3 FONT GDI-хэндла, которые даже в destructor TControl.Destroy; при вызове DestroyWindow( I ); не возвращаются.
    Соответственно, при постоянном создании-удалении окна у приложения растут GDI Handles.
    Вопрос - так и должно быть или я что-то упускаю?
  • Vladimir Kladov © (06.01.12 19:23) [1]
    Наверное, не хватает TKOLApplet?
    Demo смотрели с модальными формами? Оно gdi-ресурсы не теряет?
  • G-Host © (07.01.12 17:58) [2]
    Наличие TKOLApplet значения не имеет.
    DemoModalForm ресурсы не потребляет, но в нем и TKOLListView нет.
    А проблема как раз в ListView.

    Собственно, даже такой кусок кода создает утечку GDI-ресурсов и памяти:

    lv : TKOLListView;

    procedure TForm1.Button1Click(Sender: PObj);
    begin
     lv := NewListView(Form, lvsList, [], nil, nil, nil);
     lv.Show;
    end;

    procedure TForm1.Button2Click(Sender: PObj);
    begin
     lv.Free;
    end;

    Каждое нажатие Button1 + Button2 приводит к захвату дополнительных 1 BRUSH и 2 FONT. Потребление памяти также каждый раз увеличивается на 2 Кбайта.
  • G-Host © (08.01.12 00:56) [3]
    Обновление:

    Если взять стандартный пример DemoModalForm и добавить:
    1. в unitb.pas строку

       lv : TKOLListView;

    2. в UnitB_1.inc в конец
     Result.lv := NewListView(Result.Form, lvsList, [], nil, nil, nil);

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

    Иными словами, ресурсы теряются при каждом создании экземпляра TKOLListView.
  • Dufa © (08.01.12 17:21) [4]
    А где утечки смотрите? Memproof показал что все в норме
  • G-Host © (09.01.12 01:43) [5]
    А memproof разве контролирует GDI-ресурсы?

    GDI-ресурсы проверяю утилитой GDIView
    http://www.nirsoft.net/utils/gdi_handles.html

    Память - диспетчером задач.
  • Dufa © (09.01.12 17:26) [6]
    Количество брашей и фонтов он как раз показывает. Позже проверю GDIView'ом тогда
  • Dufa © (10.01.12 11:09) [7]
    Проверил через гдивьев, что-то не то он показывает явно. Попробуй код

    var
     //lv : TKOLListView;
     b: DWORD;

    procedure TForm1.Button1Click(Sender: PObj);
    var
     t: TLogBrush;
    begin
     //lv := NewListView(Form, lvsList, [], nil, nil, nil);
     //lv.Show;
     t.lbStyle := BS_SOLID;
     t.lbColor := DIB_RGB_COLORS;
     b := CreateBrushIndirect(t);
     form.Caption := Int2Str(b);
    end;

    procedure TForm1.Button2Click(Sender: PObj);
    begin
     //lv.Free;
     form.Caption := Int2Str(integer(DeleteObject(b)));
    end;

  • G-Host © (12.01.12 21:26) [8]
    GDIView показывает ровно то же самое, что и ProcesExplorer Русиновича и даже (!!!) стандартный Диспетчер задач в Windows (если включить в нем колонку "объекты GDI"). Последним двум я верю даже больше, чем себе :)

    А именно:
    1. Сразу после запуска за приложением числятся 14 GDI-ресурсов.
    2. После создания кисти число GDI-ресурсов становится равным 15.
    3. После удаления кисти число GDI-ресурсов остается равным 15. Это - да, непонятно.
    4. Однако при повторном создании кисти число ресурсов опять не изменяется и остается равным 15.
    5. к пункту 3.

    При создании-удалении KOLListView ситуация иная:
    1. Сразу после запуска за приложением числятся 14 GDI-ресурсов.
    2. После создания KOLListView число GDI-ресурсов становится равным 19.
    3. После удаления KOLListView число GDI-ресурсов не изменяется (!!!).
    4. При повторном создании KOLListView число GDI-ресурсов увеличивается на 3 (!!!).
    5. к пункту 3.

    Если с BRUSH-ами все не так страшно, поскольку общее число ресурсов не растет, то с ListView все достаточно плохо, поскольку каждый объект (пусть даже потом и удаленный) увеличивает число захваченных ресурсов на 3. 3333 созданных за время работы программы списков - и финиш.
  • G-Host © (12.01.12 21:54) [9]
    Забавно, что ни в VCL, ни в LCL (Lazarus) подобных фокусов с ListView не происходит - там GDI-ресурсы исправно возвращаются обратно.
  • thaddy © (15.01.12 00:22) [10]
    I just tried something.
    It seems you do not understand MemProof!
    You have to compile first with stackframes ON and full debug info.
    Otherwise MemProof will give false, incorrect results.
    If you test with these options, NO brushes and pens are leaked at all.

    This is just illusion.
    RTFM from MemProof BTW. <smile>

    To be friendly: you are not the first one who forgot this.
  • thaddy © (15.01.12 00:38) [11]
    To be fair:

    You can only test kol for memory leaks with stackframes on and {$D+}.
    You can remove that for "release".
    The reason is that kol is too efficient :-)
    If Memproof says it doesn't leak with these options, it will not leak without these options either!

    Plz let me know the results.
    I know that the code that you wrote here Does Not Leak!
  • G-Host © (15.01.12 22:04) [12]
    2 thaddy:

    Can you send me a working EXE (creating and destroying KOLListView example)?
  • G-Host © (15.01.12 22:09) [13]
    And again:

    I'm NOT using MemProof. I'm using GDIView, ProcessExplorer and standard Windows Task Manager.
    The all show the same - GDI resources leaking.

    If you have a correctly working EXE (with create/destroy KOLListView), please send me.
  • Thaddy © (16.01.12 00:43) [14]
    Send me some code in private. (you have mail)
  • Thaddy © (02.02.12 23:34) [15]
    I guess this is closed?
  • RusSun © (03.02.12 03:15) [16]
    hard to tell with such activity in this forum)
  • Thaddy © (06.02.12 16:54) [17]
    I spend some time to check the claim.
    My conclusion was right. I you debug the leaks with a good program (like AQ** or its ancestor memproof) and you follow the instructions, there are no leaks in GDI.
    There is also a directive to debug the GDI resources in KOL.
    That also doesn't give anything unusual.
    Debugging can ONLY work if you follow the rules, otherwise you get false positives for leaks.
    If G-host is still not convinced, email me with code.
  • thaddy © (06.02.12 17:02) [18]
    @RusSun: It is a bit quiet here, you are right. Doesn't mean we don't read.
  • G-Host © (10.02.12 02:02) [19]
    2 thaddy
    Sorry, I think you are wrong.
    Because this code just crash or hangs up  the application:

    procedure TForm1.Button1Click(Sender: PObj);
    var
     i : Integer;
    begin
     for I := 1 to 4000 do begin
       lv := NewListView(Form, lvsList, [], nil, nil, nil);
       lv.Show;
       lv.Free;
     end;
    end;



    GDI resources goes to 10000 and than application hangs. Why it's happens, if releasing of GDI is OK?
 
Конференция "KOL" » Утечка GDI-ресурсов [Delphi, Windows]
Есть новые Нет новых   [134427   +35][b:0][p:0.001]