德尔福内存管理
我一直无法找到几个 Delphi 内存管理问题的答案。我可以测试不同的场景(我这样做是为了找出破坏 FreeAndNil 方法的原因),但它需要太长的时间而且很难!但说真的,我也想知道你们(Delphi 开发人员)如何处理这些内存管理问题。
我的问题(请随意提出您自己的问题,我相信这些问题的答案也会对我有帮助):
FreeAndNil 适用于 COM 对象吗?我的想法是我不需要它,但如果我需要做的只是将其设置为 nil,那么为什么不在我的finally 块中保持一致并使用 FreeAndNil 来完成所有事情?
清理静态数组的正确方法是什么(myArr:TObject 的 Array[0..5])。我不能 FreeAndNil 它,那么将它设置为 nil 就足够了(在 FreeAnNil'd 每个对象之后我需要这样做吗?)?
谢谢你们!
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):
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?
Whats the proper way to clean up static arrays (myArr : Array[0..5] of TObject). I can't FreeAndNil it, so is it good enough to just set it to nil (do I need to do that after I've FreeAnNil'd each object?)?
Thanks Guys!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
COM 对象会自动进行引用计数;一旦变量超出范围或具有接口指针作为字段的对象被删除,Delphi 将调用 _Release 并且该对象将删除自身。您不需要显式地将任何内容设置为 nil。
对于静态数组,您需要循环遍历它们并显式释放每个对象。
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.
COM 对象是通过接口引用的,您无需执行任何操作即可释放它们。编译器负责必要的引用计数逻辑,以确保 COM 对象将在正确的时间被处理。
至于静态数组(或动态数组),您也不需要释放它们。如果它们包含对象,则必须在适当的时间释放对象,但数组则不需要。
另外,切勿对任何非对象引用的内容使用 FreeAndNil。将其与接口或其他变量一起使用可能会损坏内存。最好永远不要使用它(而是使用 Free),除非您正在处理需要释放并稍后重用的对象。
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.
首先,在大多数情况下,FreeAndNil 有点矫枉过正。当您在析构函数之外或全局(丑陋)变量上释放对象的字段时,这很方便。但大多数时候,只需拨打免费电话就足够了。
您应该知道,对象变量实际上是指向对象数据的指针。当您调用 Free 时,该缓冲区将被释放(当然,在析构函数运行之后),但 Object 变量仍然指向刚刚释放的内存位置。它被称为“悬空指针”。只要您知道它在该上下文中是悬空的,那么拥有悬空指针就不是问题。例如:
在您不确切知道何时或如何释放变量的情况下,调用 FreeAndNil 对全局变量更有意义。话虽如此,始终调用 FreeAndNil 并没有什么问题(除非在非常紧密的循环中,您试图获得每一盎司的性能)。
现在,对于 COM 对象...就像 Mason 所说的那样,它们是引用计数的。因此,如果您持有对该接口的唯一引用,则调用
MyInterface := nil;
将释放它。但是,当/如果变量超出范围时,编译器会添加清理代码以确保接口引用递减。因此,如果您想将内存需求保持在最低限度,请将接口设置为 nil。否则的话,也没有那么重要。至于你的数组...你可以对列表中的每个项目调用 Free...之后也可以将它们设置为 nil 。
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:
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.
对于静态数组,如果您创建了数组的内容,只需释放您创建的那些对象即可。您不需要执行任何特殊操作来清理 myArr 本身使用的空间。
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.