Q&A

  • Reference를 Release해도 Garbage가 생깁니다.
Font를 생성하여 곧바로 OleFont로 사용하려고

다음과 같은 코드를 짰습니다.



procedure TForm1.Button1Click(Sender: TObject);

var

I: Integer;

OleFont: IFontDisp;

begin

for I := 0 to 50 do begin

GetOleFont(TFont.Create, OleFont);

...

end;

end;



그런데 나중에 Garbage가 과연 생기지 않을 수 있는가 알아보기 위해서

다음과 같은 테스트를 했습니다.



procedure TForm1.Button1Click(Sender: TObject);

var

I: Integer;

OleFont: IFontDisp;

Mem: TMemoryStatus;

begin

Mem.dwLength := sizeof(Mem);

for I := 0 to 50 do begin

GetOleFont(TFont.Create, OleFont);

OleFont._Release;

OleFont := nil;

end;

GlobalMemoryStatus(Mem);

Label1.Caption := IntToStr(Mem.dwAvailPhys);

end;



그런데 이걸 테스트해보니 꾸준히 사용가능한 물리적 메모리의 양이

감소합니다.

그렇지만, for문 안에서 아무것도 하지 않아도

일시적으로는 감소하는 것도 볼 수 있었습니다.



그래서 Mem.dwAVailPhys가 과연 테스트에 적합한 것이었는지,

정말 Garbage가 발생하는 것인지, 발생한다면 무엇을 잘못한 것인지,

발생한다면 Garbage가 생기지 않게 하려면 도대체 어떻게 해야 하는지

등을 알고 싶습니다. (제 생각엔 저렇게 코딩했을때 Garbage가 생기지

않을 줄 알았습니다.)



위와 같이 하지 않고 다음과 같이 하면



Fnt := TFont.Create;

GetOleFont(Fnt, OleFont);

....

Fnt.Free;



이때는 메모리가 새는 것 같진 않더군요...

하지만 올바른 사용법인지 궁금합니다.



고견을 부탁드리겠습니다.



2  COMMENTS
  • Profile
    최용일 2000.05.03 03:39
    안녕하세요. 최용일입니다.



    GetOleFont(TFont.Create, OleFont); <-----



    위 부분에서 TFont를 생성해서 인터페이스를 얻었는데 인터페이스를 Release한다고 해도



    TFont.Create로 생성된 TFont객체는 Free가 안되어있어서 Garbage가 생기는것 같습니다.



    ^^ 항상 즐코하세요.



    김일영 wrote:

    > Font를 생성하여 곧바로 OleFont로 사용하려고

    > 다음과 같은 코드를 짰습니다.

    >

    > procedure TForm1.Button1Click(Sender: TObject);

    > var

    > I: Integer;

    > OleFont: IFontDisp;

    > begin

    > for I := 0 to 50 do begin

    > GetOleFont(TFont.Create, OleFont);

    > ...

    > end;

    > end;

    >

    > 그런데 나중에 Garbage가 과연 생기지 않을 수 있는가 알아보기 위해서

    > 다음과 같은 테스트를 했습니다.

    >

    > procedure TForm1.Button1Click(Sender: TObject);

    > var

    > I: Integer;

    > OleFont: IFontDisp;

    > Mem: TMemoryStatus;

    > begin

    > Mem.dwLength := sizeof(Mem);

    > for I := 0 to 50 do begin

    > GetOleFont(TFont.Create, OleFont);

    > OleFont._Release;

    > OleFont := nil;

    > end;

    > GlobalMemoryStatus(Mem);

    > Label1.Caption := IntToStr(Mem.dwAvailPhys);

    > end;

    >

    > 그런데 이걸 테스트해보니 꾸준히 사용가능한 물리적 메모리의 양이

    > 감소합니다.

    > 그렇지만, for문 안에서 아무것도 하지 않아도

    > 일시적으로는 감소하는 것도 볼 수 있었습니다.

    >

    > 그래서 Mem.dwAVailPhys가 과연 테스트에 적합한 것이었는지,

    > 정말 Garbage가 발생하는 것인지, 발생한다면 무엇을 잘못한 것인지,

    > 발생한다면 Garbage가 생기지 않게 하려면 도대체 어떻게 해야 하는지

    > 등을 알고 싶습니다. (제 생각엔 저렇게 코딩했을때 Garbage가 생기지

    > 않을 줄 알았습니다.)

    >

    > 위와 같이 하지 않고 다음과 같이 하면

    >

    > Fnt := TFont.Create;

    > GetOleFont(Fnt, OleFont);

    > ....

    > Fnt.Free;

    >

    > 이때는 메모리가 새는 것 같진 않더군요...

    > 하지만 올바른 사용법인지 궁금합니다.

    >

    > 고견을 부탁드리겠습니다.

    >

  • Profile
    김일영 2000.05.03 05:32
    답변 감사합니다.

    GetOleFont보니까 Font 개체에 Adapter를 붙여서 IFontDisp를 돌려주는 식이라,

    IFontDisp만 Release되면 Font 개체도 Free될 줄 믿었습니다.

    하지만 안 되는 것 같네요. (쩝~! 안타깝습니다)

    비슷한 식으로 다른 개체를 CreateOleObject하고

    Variant 변수에 받아가지고 다시 그 변수에 varNull을 대입하는

    for문을 돌려봤습니다.

    이건 쓰레기가 생기지 않는 것 같네요.

    오늘 저의 삽질이 훗날 다른 사람의 터 파기가 되겠죠?

    전 오늘 웬일인지 두통이 심하군요.

    건강하시기 바랍니다.

    ====================================================================

    최용일 wrote:

    > 안녕하세요. 최용일입니다.

    >

    > GetOleFont(TFont.Create, OleFont); <-----

    >

    > 위 부분에서 TFont를 생성해서 인터페이스를 얻었는데 인터페이스를 Release한다고 해도

    >

    > TFont.Create로 생성된 TFont객체는 Free가 안되어있어서 Garbage가 생기는것 같습니다.

    >

    > ^^ 항상 즐코하세요.

    >

    > 김일영 wrote:

    > > Font를 생성하여 곧바로 OleFont로 사용하려고

    > > 다음과 같은 코드를 짰습니다.

    > >

    > > procedure TForm1.Button1Click(Sender: TObject);

    > > var

    > > I: Integer;

    > > OleFont: IFontDisp;

    > > begin

    > > for I := 0 to 50 do begin

    > > GetOleFont(TFont.Create, OleFont);

    > > ...

    > > end;

    > > end;

    > >

    > > 그런데 나중에 Garbage가 과연 생기지 않을 수 있는가 알아보기 위해서

    > > 다음과 같은 테스트를 했습니다.

    > >

    > > procedure TForm1.Button1Click(Sender: TObject);

    > > var

    > > I: Integer;

    > > OleFont: IFontDisp;

    > > Mem: TMemoryStatus;

    > > begin

    > > Mem.dwLength := sizeof(Mem);

    > > for I := 0 to 50 do begin

    > > GetOleFont(TFont.Create, OleFont);

    > > OleFont._Release;

    > > OleFont := nil;

    > > end;

    > > GlobalMemoryStatus(Mem);

    > > Label1.Caption := IntToStr(Mem.dwAvailPhys);

    > > end;

    > >

    > > 그런데 이걸 테스트해보니 꾸준히 사용가능한 물리적 메모리의 양이

    > > 감소합니다.

    > > 그렇지만, for문 안에서 아무것도 하지 않아도

    > > 일시적으로는 감소하는 것도 볼 수 있었습니다.

    > >

    > > 그래서 Mem.dwAVailPhys가 과연 테스트에 적합한 것이었는지,

    > > 정말 Garbage가 발생하는 것인지, 발생한다면 무엇을 잘못한 것인지,

    > > 발생한다면 Garbage가 생기지 않게 하려면 도대체 어떻게 해야 하는지

    > > 등을 알고 싶습니다. (제 생각엔 저렇게 코딩했을때 Garbage가 생기지

    > > 않을 줄 알았습니다.)

    > >

    > > 위와 같이 하지 않고 다음과 같이 하면

    > >

    > > Fnt := TFont.Create;

    > > GetOleFont(Fnt, OleFont);

    > > ....

    > > Fnt.Free;

    > >

    > > 이때는 메모리가 새는 것 같진 않더군요...

    > > 하지만 올바른 사용법인지 궁금합니다.

    > >

    > > 고견을 부탁드리겠습니다.

    > >