스레드 내에서 Graphics32에서 TBitmap32와 TJpegImage를 사용하여 Jpeg이미지를 로딩 하고
TBitmap32 객체를 해제 했을 경우에 메모리 릭(Leak)이 발생하는 것 처럼 보인다.
이것은 TBitmap32문제라기 보다는 아마도 TJpegImage가 스레드에 안전하지 않은 것으로 추정된다.
테스트 프로그램을 만들어 비스레드 모드에서 이미지 로딩후 해제 하는 부분과
스레드 모드에서 로딩후 해제 하는 부분을 만들어 테스트 했을 때 메모리가 해제되지 않고 계속 남아 있는 것을 확인할 수 있는에 이 메모리 릭은 유레카 로그에도 검출되지 않는다..
[참조] http://graphics32.org/news/newsgroups.php?art_group=graphics32.general&article_id=9835
TBitmap32 객체를 해제 했을 경우에 메모리 릭(Leak)이 발생하는 것 처럼 보인다.
이것은 TBitmap32문제라기 보다는 아마도 TJpegImage가 스레드에 안전하지 않은 것으로 추정된다.
테스트 프로그램을 만들어 비스레드 모드에서 이미지 로딩후 해제 하는 부분과
스레드 모드에서 로딩후 해제 하는 부분을 만들어 테스트 했을 때 메모리가 해제되지 않고 계속 남아 있는 것을 확인할 수 있는에 이 메모리 릭은 유레카 로그에도 검출되지 않는다..
unit uMain; {** JPEGImage를 로딩하고 해제할때 메모리가 정확하게 반환이 되는지 체크 하기 위한 용도임 작성자 : 온달 작성일 : 2011.07.23 아이서퍼3 내부에서 기사 Draw부분에서 로컬 파일을 읽어서 보여주고 해제 하는데 메모리가 감소하지 않는 문제 처리 테스트 - 스레드와 비스레드내에서... } interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, GR32, jpeg, StdCtrls, ExtDlgs, GR32_Image, ExtCtrls; type TForm1 = class(TForm) OpenPictureDialog1: TOpenPictureDialog; Button1: TButton; Button2: TButton; Panel1: TPanel; iv: TImgView32; Memo1: TMemo; Button3: TButton; Button4: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end; TGThread = class(TThread) public FBitmap : TBitmap32; procedure Draw; // SyncFunction procedure Execute; override; end; var Form1: TForm1; implementation {$R *.dfm} {** 지정한 파일로부터 이미지를 로딩합니다. ( 지원하는 포맷 : JPEG, PNG, BMP, GIF ) @param ABitmap32 로딩한 이미지를 @param @result 이미지 로딩이 성공하면 true, 실패하면 false 반환 *} function LoadBitmap32FromImageStream(ABitmap32: TBitmap32; AStream: TStream): boolean; var AJpegImage: TJpegImage; ABitmap: TBitmap; begin Result := false; if (0 = AStream.Size) then exit; ABitmap := TBitmap.Create; try try AJpegImage := TJpegImage.Create; AStream.Seek(0, 0); AJpegImage.LoadFromStream(AStream); ABitmap.Assign(AJpegImage); ABitmap32.Assign(ABitmap); finally AJpegImage.Free; end; Result := true; except //modified by niceondal, 2011.07.23, 원래는 finally로 되었음 Result := false; end; ABitmap.Free; end; {** 지정한 파일로부터 이미지를 로딩합니다. ( 지원하는 포맷 : JPEG, PNG, BMP, GIF ) @param ABitmap32 로딩한 이미지를 @param @result 이미지 로딩이 성공하면 true, 실패하면 false 반환 *} function LoadBitmap32FromImageFile(ABitmap32: TBitmap32; const strFileName: string): boolean; var AMemoryStream: TMemoryStream; begin Result := false; if (not FileExists(strFileName)) then exit; AMemoryStream := TMemoryStream.Create; try AMemoryStream.LoadFromFile(strFileName); Result := LoadBitmap32FromImageStream(ABitmap32, AMemoryStream); finally AMemoryStream.Free; end; end; procedure TForm1.Button1Click(Sender: TObject); var ABitmap32 : TBitmap32; begin ABitmap32 := TBitmap32.Create; LoadBitmap32FromImageFile(ABitmap32, 'C:\Temp\3e4e32aa141be3e2345b.jpg'); ABitmap32.Free; end; procedure TForm1.Button2Click(Sender: TObject); var ABitmap32 : TBitmap32; jpeg : TJpegImage; bmp : TBitmap; begin ABitmap32 := TBitmap32.Create; jpeg := TJpegImage.Create; bmp := TBitmap.Create; jpeg.LoadFromFile('C:\Temp\3e4e32aa141be3e2345b.jpg'); bmp.Assign(jpeg); ABitmap32.Assign(bmp); bmp.free; jpeg.free; ABitmap32.Free; end; { TGThread } procedure TGThread.Draw; begin form1.iv.Bitmap.Assign(FBitmap); form1.iv.Refresh; sleep(200); end; procedure TGThread.Execute; var i : integer; ABitmap : TBitmap32; begin for i := 0 to form1.memo1.Lines.count-1 do begin ABitmap := TBitmap32.Create; LoadBitmap32FromImageFile(ABitmap, form1.memo1.lines[i]); FBitmap := ABitmap; Synchronize(Draw); ABitmap.Free; end; end; procedure TForm1.Button3Click(Sender: TObject); var i : integer; ABitmap : TBitmap32; begin for i := 0 to memo1.Lines.count-1 do begin ABitmap := TBitmap32.Create; LoadBitmap32FromImageFile(ABitmap, memo1.lines[i]); iv.Bitmap.Assign(ABitmap); iv.Refresh; sleep(100); ABitmap.Free; end; end; procedure TForm1.Button4Click(Sender: TObject); var th : TGThread; begin th := TGThread.Create(false); th.Resume; end; end.
[참조] http://graphics32.org/news/newsgroups.php?art_group=graphics32.general&article_id=9835
'프로그래밍 > Delphi' 카테고리의 다른 글
DrawText를 이용한 WrapedText의 높이 구하기 (0) | 2011.08.01 |
---|---|
TBitmap32는 Thread내에서 Memory Leak이 발생 해법 (0) | 2011.07.25 |
GDI객체 및 기본 윈도우 메모리 힙 할당문제 (1) | 2011.07.23 |
JPEG/GIF/BMP/PNG/PCX등 이미지 관련 정보를 간단히 얻기 (0) | 2011.07.21 |
이미지 파일명을 가지고 이미지 사이즈(폭/높이) 알아내기 (0) | 2011.07.19 |