본문 바로가기

프로그래밍/Delphi

TBitmap32는 Thread내에서 Memory Leak이 발생 해법

아 이문제 때문에 고생고생 했는데 결국은 잡았다.... 해방된 기분

이 문제는 TBitmap32에 비트맵(TBitmap) 기반 Assign하는 동작이 스레드 내에서 안전하지 않기 때문으로
증상은 할당후 여타 작업을 수행 후에 TBitmap 객체를 해제 해도 메모리에서 제거되지 않는 문제임.

이 메모리 누수 현상은 유레카 로그에서도 메모리 릭으로 검출되지 않음.

해결책은 다음과 같습니다.

GR32.pas 소스를 수정해야 함
procedure TCustomBitmap32.Assign(Source: TPersistent); 함수내에 서브 함수중 Bitmap을 이용한 Assign 부분을 수정
  procedure AssignFromBitmap(TargetBitmap: TCustomBitmap32; SrcBmp: TBitmap);
  var
    TransparentColor: TColor32;
    DstP: PColor32;
    I: integer;
    DstColor: TColor32;
  begin
    SrcBmp.Canvas.Lock; //-- Add by niceondal for memory leaks in Thread

    AssignFromGraphicPlain(TargetBitmap, SrcBmp, 0, SrcBmp.PixelFormat <> pf32bit);
    if TargetBitmap.Empty then Exit;

    if SrcBmp.Transparent then
    begin
      TransparentColor := Color32(SrcBmp.TransparentColor) and $00FFFFFF;
      DstP := @TargetBitmap.Bits[0];
      for I := 0 to TargetBitmap.Width * TargetBitmap.Height - 1 do
      begin
        DstColor := DstP^ and $00FFFFFF;
        if DstColor = TransparentColor then
          DstP^ := DstColor;
        Inc(DstP);
      end;
    end;

    if Supports(TargetBitmap.Backend, IFontSupport) then // this is optional
      (TargetBitmap.Backend as IFontSupport).Font.Assign(SrcBmp.Canvas.Font);

    SrcBmp.Canvas.UnLock; //-- Add by niceondal for memory leaks in Thread
  end;