【问题标题】:Cleanup before termination?终止前清理?
【发布时间】:2012-11-05 12:41:41
【问题描述】:

这个问题困扰了我一段时间:我在 MSDN 的 DirectX article 中阅读了以下内容:

析构函数(应用程序的) 应该释放所有存储的(Direct2D) 接口...

DemoApp::~DemoApp()
{
    SafeRelease(&m_pDirect2dFactory);
    SafeRelease(&m_pRenderTarget);
    SafeRelease(&m_pLightSlateGrayBrush);
    SafeRelease(&m_pCornflowerBlueBrush);
}

现在,如果应用程序的所有数据都在终止时被释放/解除分配 (source),为什么我还要麻烦地按顺序创建一个函数/并单独释放它们?这毫无意义!

随着时间的推移,我越来越多地看到这种情况,这显然让我很烦恼。 上面的 MSDN 文章是我第一次遇到这种情况,因此在所有其他情况下提及它是有道理的。

好吧,既然到目前为止我还没有真正问过我的问题,那就是:

  • 我需要在终止前释放一些东西吗? (请解释原因)
  • MSDN 中的作者为什么选择这样做?
  • 答案是否与本机代码和托管代码不同? IE。在编写 C# 程序时,是否需要确保在程序结束时处理所有内容? (我不了解 Java,但如果存在处置,我相信其他成员也会对此表示赞赏)。

谢谢!

【问题讨论】:

  • 嗯,内存是唯一的一种资源。虽然内存会被操作系统释放(因为它足够智能),但其他一些资源可能会丢失。
  • 这个问题是关于 C++ 还是 C#?他们会有非常不同的答案!
  • @MooingDuck 我实际上已经问过(最后一个问题)这两种情况的答案是什么。

标签: c# c++ garbage-collection dispose


【解决方案1】:

当您的应用程序终止时,您无需担心托管内容。当整个进程的内存被销毁时,所有这些都会随之而来。

重要的是非托管资源。

如果您对文件进行了锁定,并且当应用程序关闭时文件处理程序的托管包装被删除,而您却没有释放锁定,那么您现在已经丢弃了唯一允许访问该文件的密钥。

如果您有一个内部缓冲区(例如用于记录错误),您可能希望在应用程序终止之前刷新它。不这样做可能意味着不会记录导致应用程序结束的致命错误。那可能……不好。

如果您打开了网络连接,则需要关闭它们。如果您不这样做,那么操作系统可能不会为您执行此操作(至少暂时不会;最终它可能会注意到不活动),这对另一端的任何人来说都是相当粗鲁的。他们可能会继续收听回复,或继续向您发送信息,却不知道您已不在。

【讨论】:

    【解决方案2】:

    现在,如果应用程序的所有数据都被释放/释放 在终止时(来源)我为什么要费力去做 一个函数按顺序/并单独释放它们?

    很多原因。一个直接的原因是因为并非所有 资源 都是内存。只有内存在进程终止时被回收。如果您的某些资源是诸如共享互斥锁或文件句柄之类的东西,那么不释放这些资源可能会弄乱其他程序或您程序的后续运行。

    我认为还有一个更重要、更根本的原因。自己不清理只是懒惰、草率的编程。如果您在终止时的清理工作很懒惰和马虎,那么您在其他时候是否也很懒惰和马虎?如果你的倾向是懒惰和马虎,并且只在你意识到潜在问题的特定领域超越这种倾向,那么你的倾向就是懒惰和马虎。如果有你没有意识到的潜在问题怎么办?你怎么能依靠你懒惰、草率编程的整体哲学来编写正确、健壮的程序?

    不要成为那个人。自己清理干净。

    【讨论】:

    • 到了懒惰的地步,我不同意。要么拆除应用程序来处理它,你不需要,或者它不需要,你需要。我知道我不会在预定拆除的前一天花时间在一座被谴责的建筑物中擦​​地板。
    • 让一个程序把东西留给操作系统清理并不一定是懒惰的编程,但程序员应该知道正在做出什么假设,并确保一些特定的规范保证这样的假设实际上是正确的。即使框架或操作系统指定在放弃某些东西之前应该明确地清理它们,但如果它们在没有清理的情况下被放弃,它们通常仍会尝试清理它们;这种自动清理“似乎有效”的事实并不意味着它是可靠的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多