C#:以与分配相反的顺序处理资源是否有优势?
许多年前,我被告诫要尽可能以与分配方式相反的顺序释放资源。也就是说:
block1 = malloc( ... );
block2 = malloc( ... );
... do stuff ...
free( block2 );
free( block1 );
我想在 640K MS-DOS 机器上,这可以最大限度地减少堆碎片。在 C# /.NET 应用程序中执行此操作是否有任何实际优势,或者这种习惯是否已经过时了?
Many years ago, I was admonished to, whenever possible, release resources in reverse order to how they were allocated. That is:
block1 = malloc( ... );
block2 = malloc( ... );
... do stuff ...
free( block2 );
free( block1 );
I imagine on a 640K MS-DOS machine, this could minimize heap fragmentation. Is there any practical advantage to doing this in a C# /.NET application, or is this a habit that has outlived its relevance?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果你的资源创建得很好,这应该不重要(太重要)。
然而,许多创建不当的库没有进行适当的检查。与分配相反的方式处置资源通常意味着您首先处置依赖于其他资源的资源 - 这可以防止编写不当的库引起问题。 (在这种情况下,您永远不会处置资源,然后使用依赖于第一个资源的存在的资源。)
这也是一个很好的做法,因为您不会过早意外地处置其他对象所需的资源。
下面是一个例子:看一个数据库操作。您不想在关闭/处置命令(使用连接)之前关闭/处置连接。
If your resources are created well, this shouldn't matter (much).
However, many poorly created libraries don't do proper checking. Disposing of resources in reverse of their allocation typically means that you're disposing of resource dependent on other resources first - which can prevent poorly written libraries from causing problems. (You never dispose of a resource, then use one that's depending on the first's existence in this case.)
It also is good practice, since you're not going to accidentally dispose a resource required by some other object too early.
Here's an example: look at a database operation. You don't want to close/dispose your connection before closing/disposing your command (which uses the connection).
别打扰。 GarbageCollector 保留对堆上的对象进行碎片整理和移动的权利,因此不知道事物的顺序。
此外,如果您要处置 A 和 B 以及 A 引用 B,那么当您处理 A 时,如果 A 处置 B 也没关系 。 dispose A,因为 Dispose 方法应该可以多次调用而不会引发异常。
Don't bother. The GarbageCollector reserves the right to defragment and move objects on the heap, so there's no telling what order things are in.
In addition, if you're disposing A and B and A references B it shouldn't matter if A disposes B when you dispose A, since the Dispose method should be callable more than once without an exception being thrown.
如果您指的是对象上的析构函数被调用的时间,那么那就是垃圾收集器,编程对其影响很小,并且根据语言定义,它是明确的非确定性的。
如果您指的是调用 IDisposable.Dispose(),那么这取决于实现 IDisposable 接口的对象的行为。
一般来说,顺序对于大多数 Framework 对象来说并不重要,除非它对调用代码很重要。但是,如果对象 A 保持对对象 B 的依赖关系,并且对象 B 已被释放,那么不要对对象 A 执行某些操作很重要。
在大多数情况下,不会直接调用 Dispose(),而是调用它隐式地作为 using 或 foreach 语句的一部分,在这种情况下,根据语句嵌入,逆序模式将自然出现。
If you are referring to the time the destructor on the objects gets called, then that's up the garbage collector, the programming can have very little influence over that, and it is explicity non-deterministic according to the language definition.
If you are referring to calling IDisposable.Dispose(), then that depends on the behavior of the objects that implement the IDisposable interface.
In general, the order doesn't matter for most Framework objects, except to the extent that it matters to the calling code. But if object A maintains a dependency on object B, and object B is disposed, then it could very well be important not to do certain things with object A.
In most cases, Dispose() is not called directly, but rather it is called implicitly as part of a using or foreach statement, in which case the reverse-order pattern will naturally emerge, according to the statement embedding.
嵌套的“使用”向您展示了“过时的”并没有真正存在,而且很少存在(不是说经过 40 年的证据证明永远不会)。这包括在 CMOS 上运行的基于堆栈的虚拟机。
[ 尽管 MSDN.com 和 Duffius 尝试让它消失,但您知道为您管理这一切,这就是堆和堆栈之间的区别。多么聪明的主意……在太空]
Nested 'usings' shows you the 'outlived' is not really on, and rarely is (not to go and say never after 40 years of evidence).. And that includes the stack-based VM that runs on say CMOS.
[ Despite some attempts by MSDN.com and Duffius to make it vanish, you know manage it all for you the difference between the heap and stack. What a smart idea.. in space ]
http://msdn.microsoft.com/en-us/magazine/bb985010。 aspx
因此,您可以随心所欲地担心您的 LIFO 处置语义,但如果您泄漏了一个,则 Dispose() 将以 CLR 想要的任何顺序被调用。
(这或多或少是威尔上面所说的)
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
So you can worry about your LIFO dispose semantics as much as you like, but if you leak one, the Dispose()'s are going to be called in whatever order the CLR fancies.
(This is more or less what Will said, above)