Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »
Страницы: 1 2 3 4 5 6

KOL 3.23 [Delphi, Windows]


Vladimir Kladov ©   (22.02.15 20:12[20]

Вот здесь полезная информация:
Текущий дамп памяти из 256 байт начиная с адреса 7EF43120:

Запускаем программу (F8), в Watches добавляем PDWORD($7EF43120), ставим "Break when changed", и каждый раз, когда первые 4 байта меняются, будет останов. Тут можно посмотреть, кто выделил.

Вообще похоже на то, что было добавление в TList, сам TList никто не освободил.


Vladimir Kladov ©   (22.02.15 20:18[21]

Фреймы даже не буду сейчас смотреть, уже просто не помню, что там и как.

Я вообще не вижу проблемы с утечками памяти. Если не мегабайтами течет. В современных приложениях вообще всё течет. Вин-8 - это просто одна сплошная протечка. Проги на шарпах со сборщиками мусора - там вообще не поймешь, то ли они текут беспрерывно, то ли это стратегия такая - мусор собирать раз в сутки.

Вот утечки ресурсов - это серьезно. Можно винду завалить, даже и 7-ку. 8-ку не пробовал (мало я с ней работал), но почему-то есть подозрение, что там ничего не изменилось.


QAZ   (22.02.15 20:26[22]


> Проги на шарпах

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

для меня утечка это как минимум сигнал что что то не так, а если что то не так, то в итоге накопится куча неразгребешь
вот с меню разобрались, сразу стали видны "скрытые" им другие проблемы

про фреймы хотяб скажи правильно ли им так назначать "родителя" и как их освобождать, просто фри или еще чего надо?


QAZ   (22.02.15 20:42[23]


> [+] Метод TBitmap.CopyToClipboard переименован в CopyToClipboardAsDIB,
>  добавлена другая версия CopyToClipboard, использующая формат
> CF_BITMAP (существенно более короткий код).

и пока я шарю в клипбордах :)
CopyToClipboardAsDIB - вообще нафиг не нужна
CF_DIB, CF_DIBV5 и CF_BITMAP взаимно конвертируются самой виндой при запросе конкретного варианта, а в 8ке вся эта метрошная лабуда вообще только CF_BITMAP должна посылать в буфер


Vladimir Kladov ©   (22.02.15 21:17[24]


> правильно ли им так назначать "родителя" и как их освобождать

Я сейчас точно уже не скажу как. В свете сегодняшних рытьёв наверное правильно сказать MyFrame.Form.Close; И да, я знаю, что это не форма, а, в общем-то, панель. Просто отправляется WM_CLOSE, дальше все по свистку от винды.


> CopyToClipboardAsDIB - вообще нафиг не нужна

Пусть останется. Я работал с битмапами, которые бывают только в DIB'е, потому что handle винде выделить не получается, слишком большой. И для совместимости.


Thaddy ©   (23.02.15 17:34[25]

I've merged 3.23++ into 64 bit unofficial. Plz test.
Link is:
http://thaddy.org/kol323-x64-unofficial.7z


Thaddy ©   (23.02.15 17:47[26]

This also contains function format for Freepascal and updated koldef.inc for Freepascal 3.0.1/3.1.1


Vladimir Kladov ©   (24.02.15 11:09[27]


> merged 3.23++

too fast. An error in asm version of run. it should be:

procedure Run( var AppletCtl: PControl );
asm
//----- if  AppletCtl = nil then Exit;
       TEST      EAX, EAX
       JZ        @@exit
       PUSH      EBX
       XCHG      EBX, EAX

//----- AppletRunning := TRUE;
       INC       [AppletRunning]

//----- Applet := AppletCtl;
       MOV       EAX, [EBX]
       MOV       [Applet], EAX

//----- AppletCtl.CreateWindow;
       CALL      CallTControlCreateWindow

//----- WHILE NOT AppletTerminated DO
@@loop: CMP       [AppletTerminated], 0
       JNZ       @@end_loop

//----- WaitMessage;
       CALL      WaitMessage

//----- AppletCtl.ProcessMessages;
       MOV       EAX, [EBX]
       CALL      TControl.ProcessMessages

       {$IFDEF   USE_OnIdle}
//----- ProcessIdle(AppletCtl);
       MOV       EAX, [EBX]
       CALL      [ProcessIdle]
       {$ENDIF}

       JMP       @@loop
@@end_loop:

       {$IFDEF LET_MENU_LEAK}
       MOV       ECX, [EBX]
       XCHG      EAX, EBX
       POP       EBX
       JECXZ     @@exit
       {$ELSE}
       POP       EBX
       LEA       EAX, [Applet]
       CMP       [EAX], 0

       JZ        @@exit
       {$ENDIF}
       CALL      TerminateExecution
@@exit:
end;


QAZ   (24.02.15 11:20[28]


>  Но исправление слишком радикальное, меняется порядок уничтожения
> окон. Может вылезти что угодно. Поэтому все можно будет
> вернуть по заклинанию LET_MENU_LEAK.

в общем печаль-тоска подобралась незаметно, есть новый виновник утечек и вылетов ---- KOLApplet
обнаружил при попытке разборок с фреймами, мысль была что может без него им плохо живется, ну типа по аналогии с несколькими формами
ток положил на форму и хобана + еще 8 утечек

потом
1)беру болванку эксперимента с меню, что выкладывал здесь, для приличия добавил 2ю форму, без апплета, запустил\закрыл - чисто
2) кладу аплет, запустил\закрыл - стоп в CPU-окне отладчика на user32.DestroyWindow
3) думаю, предупреждал же...
4) ставлю дефин LET_MENU_LEAK, удалил меню, для чистоты эксперимента, запустил\закрыл - 9 утечек, включая те самые Тлисты....
5) убираю аплетт, , запустил\закрыл - портянка на весь экран ошибка памяти
6) убираю дефин LET_MENU_LEAK, запустил\закрыл - чисто

кино ннада?


QAZ   (24.02.15 11:26[29]


> беру болванку эксперимента с меню

с дефином PAS_VERSION, чудеса не менее интересные, включая "рунтаймеррор"


Thaddy ©   (24.02.15 12:31[30]

Package is now updated as per Vladimir's change. (kol_asm.inc)


Vladimir Kladov ©   (24.02.15 13:08[31]

Вот где ошибка:

procedure TerminateExecution( var AppletCtl: PControl );
var App: PControl;
   Appalreadyterminated: Boolean;
begin
 Appalreadyterminated := AppletTerminated;
 AppletTerminated := TRUE;
 AppletRunning := FALSE;
 App := Applet;
 Applet := nil;
 if (App <> nil) {and (App.RefCount >= 0)} then
 begin
   {$IFDEF LET_MENU_LEAK} //was IFNDEF !!!
   App.RefInc;
   {$ENDIF}
   if not Appalreadyterminated then
   begin
     App.ProcessMessages;
     App.Perform( WM_CLOSE, 0, 0 );
   end;
   AppletCtl := nil;
   {$IFNDEF LET_MENU_LEAK}            //   версия KOL 3.23+:
           DestroyWindow(App.Handle); //** В этом варианте вызывается не деструктор
   {$ELSE}                            //   объекта, а функция закрытия окна. Вызов
           App.Free;
           App.RefDec;                //   деструктора выполнится в обработчике
   {$ENDIF}                           //   события WM_DESTROY. В результате, сначала
 end;                                 //   успешно разрушится меню формы. 22.02.2015
end;


и вот тут, соответственно (kol_asm.inc, + перенос кода за скобки ifdef'а, так что лучше всю процедуру заменить):
procedure TerminateExecution( var AppletCtl: PControl );
asm
         PUSH EBX
         PUSH ESI
         MOV  BX, $0100
         XCHG BX, word ptr [AppletRunning]
         XOR  ECX, ECX
         XCHG ECX, [Applet]
         JECXZ @@exit

         PUSH EAX

         {$IFDEF LET_MENU_LEAK} // Was IFNDEF !!!
         XCHG EAX, ECX
         MOV  ESI, EAX
         CALL TObj.RefInc
         {$ENDIF}

         TEST BH, BH
         JNZ  @@closed

         MOV  EAX, ESI
         CALL TControl.ProcessMessages
         PUSH 0
         PUSH 0
         PUSH WM_CLOSE
         PUSH ESI
         CALL TControl.Perform
@@closed:
         POP  EAX
         XOR  ECX, ECX
         MOV  dword ptr [EAX], ECX
         {$IFDEF LET_MENU_LEAK}
              MOV  EAX, ESI
              CALL TObj.RefDec
              XCHG EAX, ESI
              CALL TObj.RefDec
         {$ELSE}
              PUSH [ESI].TControl.FHandle
              CALL Windows.DestroyWindow
         {$ENDIF}
@@exit:
         POP  ESI
         POP  EBX
end;


Vladimir Kladov ©   (24.02.15 13:10[32]


> Package is now updated as per Vladimir's change. (kol_asm.
> inc)

Thaddy, you are still too fast! :)


QAZ   (24.02.15 15:41[33]


> Vladimir Kladov ©   (24.02.15 13:08) [31]

да-да по крайней мере паскальный вариант, самый большой проект, где был Tlist в логе - это и было изза апплета, сейчас все чисто

остался только косяк с фреймами (или табами) в другом

> Запускаем программу (F8), в Watches добавляем PDWORD($7EF43120),
>  ставим "Break when changed", и каждый раз, когда первые
> 4 байта меняются, будет останов. Тут можно посмотреть, кто
> выделил.

чет в 7ке нет такого "Break when changed" и пролетает мимо ненаходит


Vladimir Kladov ©   (24.02.15 15:59[34]

PDWORD(адрес)^ - разыменовать надо.


Vladimir Kladov ©   (24.02.15 16:07[35]

Обновил KOL.zip на kolmck.net.


QAZ   (24.02.15 20:40[36]

табконтрол вроде не причём, на панелях также
фастмм указывает на создание фрейма в файлах типа Unit2_1.inc
procedure NewForm2( var Result: PForm2; AParent: PControl );
begin

 {$IFDEF KOLCLASSES}
 Result := PForm2.Create;
 {$ELSE OBJECTS}
 New( Result, Create );<<<<<<<<<<<<<<<<<<<<<<<<<<
 {$ENDIF KOL CLASSES/OBJECTS}
 Result.Form := NewPanel( AParent, esNone ).MarkPanelAsForm;
 Result.Form.DF.FormAddress := @ Result.Form;
 Result.Form.DF.FormObj := Result;
   Result.Form.SetClientSize( 468, 278 );
   Result.EditBox1 := NewEditBox( Result.Form, [  ] ).SetPosition( 168, 104 );
   Result.EditBox1.Text := 'EditBox1';
   Result.EditBox1.Color := TColor(clWindow);
   Result.Form.CreateWindow;

end;

показано <<<<<<<<<<<<<
хоть free, хоть close - одинаково


Dimaxx ©   (25.02.15 00:43[37]

KOL_asm.inc:

procedure Run( var AppletCtl: PControl );
asm
//----- if  AppletCtl = nil then Exit;
      TEST      EAX, EAX
      JZ        @@exit
      PUSH      EBX
      XCHG      EBX, EAX

//----- AppletRunning := TRUE;
      INC       [AppletRunning]

//----- Applet := AppletCtl;
      MOV       EAX, [EBX]
      MOV       [Applet], EAX

//----- AppletCtl.CreateWindow;
      CALL      CallTControlCreateWindow

//----- WHILE NOT AppletTerminated DO
@@loop: CMP       [AppletTerminated], 0
      JNZ       @@end_loop

//----- WaitMessage;
      CALL      WaitMessage

//----- AppletCtl.ProcessMessages;
      MOV       EAX, [EBX]
      CALL      TControl.ProcessMessages

      {$IFDEF   USE_OnIdle}
//----- ProcessIdle(AppletCtl);
      MOV       EAX, [EBX]
      CALL      [ProcessIdle]
      {$ENDIF}

      JMP       @@loop
@@end_loop:

      {$IFDEF LET_MENU_LEAK}
      MOV       ECX, [EBX]
      XCHG      EAX, EBX
      POP       EBX
      JECXZ     @@exit
      {$ELSE}
      POP       EBX
      LEA       EAX, [Applet]
      CMP       [EAX], 0         <-ОШИБКА!!!!
      JZ        @@exit
      {$ENDIF}
      CALL      TerminateExecution
@@exit:
end;


Dimaxx ©   (25.02.15 00:46[38]

В destructor TMenu.Destroy не используется (но определяется) Next.


Vladimir Kladov ©   (25.02.15 05:35[39]


> CMP       [EAX], 0         <-ОШИБКА!!!!

Какая? В Delphi7 ошибки нет. У вас что, Free Pascal? Delphi 201x? Пишите яснее.


> В destructor TMenu.Destroy не используется (но определяется)
> Next.


destructor TMenu.Destroy;
var Next, Prnt: PMenu;
   {$IFNDEF LET_MENU_LEAK}
   Save_Ref: Integer;
   {$ENDIF}
begin
 {$IFDEF DEBUG_MENU_DESTROY}
 LogFileOutput( GetStartDir + 'TMenu.Destroy.txt',
   Int2Hex( DWORD( @ Self ), 6 ) + ' ' + Int2Str( RefCount ) );
 {$ENDIF}
 if Count > 0 then
 begin
   FMenuItems.ReleaseObjects;
   FMenuItems := NewList;
 end;
 if FParentMenu <> nil then
 begin
   {$IFNDEF LET_MENU_LEAK}
   Save_Ref := Self.fRefCount; //** Очень грязный хак, конечно. Цель: предотвратить
   Self.fRefCount := 17;       //   попытку повторного уничтожения этого объекта меню.
   {$ENDIF}
       Prnt := FParentMenu;
       Next := Prnt.RemoveSubMenu( FId );
       FParentMenu := nil;
       Prnt.FMenuItems.Remove( @ Self );
   {$IFNDEF LET_MENU_LEAK}
       Self.fRefCount := Save_Ref; //** Можно было бы и не восстанавливать.
   {$ELSE}
       if Next = nil then Exit;    //** Пришлось закомментарить. Вызывало утечку.
   {$ENDIF}
 end;
  if (FControl <> nil) and (FControl.fMenu = FHandle) and (FHandle <> 0) then
  begin
    if  {$IFDEF USE_FLAGS} not (G2_Destroying in FControl.fFlagsG2)
        {$ELSE} not FControl.fDestroying {$ENDIF} then //!!!fix by Galkov
    begin
      Windows.SetMenu( FControl.fHandle, 0 );
      // this removes main menu from window, but does not destroy it
    end;
    FControl.fMenu := 0;
    Next := PMenu( FControl.fMenuObj );
    while Next <> nil  do
    begin
      if Next.fNextMenu = @Self then
      begin
        Next.fNextMenu := fNextMenu;
        break;
      end;
      Next := Next.fNextMenu;
    end;
  end;
  Next := fNextMenu;
  if FBitmap <> 0 then
    Bitmap := 0;
  if FHandle <> 0 then
  begin
    //if not
    DestroyMenu( FHandle )
    // then LogFileOutput( GetStartDir + 'err.log.txt', SysErrorMessage( GetLastError ) )
    ;
  end;
  FCaption := '';
  FMenuItems.Free;
  Next.Free;
  inherited;
  // all later created (popup) menus (of the same control)
  // are destroyed too
end;

Расскажите уже, каким компилятором пользуетесь, что он такую чушь сказал.


Страницы: 1 2 3 4 5 6 версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо