开发者

Delphi Memory Management

I haven't been able to find the answers to a couple of my Delphi memory management questions. I could test different scenarios (which I did to find out what breaks the FreeAndNil method), but its takes too long and its hard! But seriously, I would also like to know how you all (Delphi developers) handle these memory management issues.

My Questions (Feel free to pose your own I'm sure the answers to them will help me too):

  1. Does FreeAndNil work for COM objects? My thoughts are I don't need it, but if all I need to do is set it to nil than why not stay consistent in my finally block and use FreeAndNil for everything?

  2. Whats the proper way to clean up static arrays (myArr : Array[0..5] of TObject). I can't FreeAndNil it, so is it go开发者_JAVA技巧od enough to just set it to nil (do I need to do that after I've FreeAnNil'd each object?)?

Thanks Guys!


COM objects are referenced via Interfaces, which you don't need to do anything to free. The compiler takes care of the necessary reference-counting logic to make sure the COM object will be disposed of at the right time.

As for static arrays, (or dynamic arrays, for that matter,) they don't need to be freed by you either. If they contain objects then the objects have to be freed at the appropriate time, but the arrays don't.

Also, never use FreeAndNil on anything that's not an object reference. Using it with interfaces or other variables can corrupt memory. It's best to never use it (use Free instead) unless you're dealing with an object that you need to free and then reuse later.


First, in most situation, FreeAndNil is a bit of overkill. It's handy when you free and object's field outside it's destructor, or on a global(ugly) variable. But most of the time, just calling free is enough.

As you should know, an object variable is actually a pointer to the object's data. When you call Free, that buffer is freed (after the destructor is ran, of course), but the Object variable still points to the memory position that was just freed. It's called a "Dangling pointer". Having a dangling pointer is not a problem as long as you KNOW it's dangling in that context. For exemple:

Procedure Myproc;
var vString : TStringList;
begin
  //Here, vString is "dangling"
  vString := TStringList.Create;
  //Here, vString is valid
  try
    //Do some stuff
  finally
    vString.Free;
  end;
  //Here, vString is "dangling"...  But who care, it's about to go out of scope and we won't use it again.
end;

Calling FreeAndNil makes more sense on global variable where you don't know exactly when or how the variable can be freed. With that being said, there is nothing wrong in calling FreeAndNil all the time (except in very tight loops where you try to get every oz of performance).

Now, for the COM objects... Like Mason stated, they are reference counted. So if you hold the only reference to that interface, calling MyInterface := nil; will free it. But when/if the variable goes out of scope, the compiler take care of adding cleanup code to make sure the interface reference is decremented. So if you are trying to keep the memory requirement to a minimum, set the interface to nil. Otherwise, it doesn't matter that much.

As for your array... You can just call Free on every items in the list... Optionnaly set them to nil after.


Regarding static arrays, if you created the contents of the array, just free those objects you created. You don't need to do anything special to clean up the space used by myArr itself.


COM objects are automatically reference counted; as soon as variable goes out of scope or the object that has the interface pointer as a field is deleted Delphi will call _Release and the object will delete itself. You don't need to set anything to nil explicitly.

For static arrays you need to loop over them and free each object explicitly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜