在Delphi中,将owner设置为Application而不是nil的好处是什么?

3

"Application" 是 VCL 的一部分,因此不是线程安全的(可能在维护其拥有的非线程安全组件列表方面存在问题)。

我正在处理的项目中有几个实例将 Application 设置为 Owner,而 Self 不是一个选项(类方法)。我想在这种情况下传递 "nil",因为该变量在函数结束时被释放。

假设有人忘记释放一个由 Application 拥有的变量:

当应用程序关闭时,内存会被释放。但我也读到 Windows 跟踪每个进程分配的内存。因此,理论上,如果一个 nil-owned 变量没有被释放,Windows 将在应用程序/进程终止时释放它。

那么,将所有者设置为 Application 与 Nil 相比有什么好处呢?

以下问题讨论了释放 nil-owned 变量的责任,但仅止于此:

组件构造函数中 nil owner 的含义是什么

1个回答

5
虽然系统在进程终止时会释放内存,但是执行过程中的泄漏可能是一个潜在的问题。如果程序执行重复动作,并且每次都有内存泄漏,则这些泄漏会随着时间的推移而逐渐累积,最终导致内存不足的情况。
同样的事情也会发生在由应用程序单例对象所拥有的组件身上。如果它们没有被显式销毁,那么它们只有在应用程序终止时才会被销毁。同样地,这些泄漏在进程执行期间可能会逐渐增加。
检测泄漏的正常方法是跟踪执行过程中的所有分配,然后在进程终止的最后一步,检查所有分配是否有相应的释放。这个功能由各种工具提供,但在Delphi环境中,FastMM内存管理器是最常用的提供此功能的工具。
如果你创建了一个由应用程序对象拥有的组件,并且没有显式销毁它,当泄漏检测器执行时,它将不会显示为已泄漏。这是不可取的,因为你真正存在着未被检测到的泄漏。
这个论点导致了一个结论,在你描述的情况下,拥有 unowned 组件将是更可取的。
另一方面,有时你创建的组件希望与应用程序对象一样长寿,可能很难找到一个好的位置在代码中显式销毁它们。在这种情况下,由应用程序对象拥有它们是一个不错的方法。这正是 owner 机制的设计目的。
我的经验法则是:
  1. 如果组件是通过流式系统(即表单)创建的,则使用拥有机制确保正确的生命周期管理,您无需在代码中执行任何操作。
  2. 如果您在代码中显式创建组件,则最好遵循正常的创建模式,并在代码中显式销毁它。在这种情况下,请使组件为 unowned。
  3. 如果您很难找到一个好的位置来销毁组件,并且可以将其生命周期与另一个组件(即应用程序)联系起来,则将该组件作为所有者传递。
回到你问的问题。你要求给出使用应用程序对象作为所有者的优势。如上所述,在许多情况下,拥有这样的组件实际上是不划算的。但也有时将应用程序对象作为所有者是有优势的。
总之,没有单一的硬性规则可遵循。您需要理解所有权的影响,然后为每个组件选择适当的所有者,这可能因情况而异。

FastMM没有报告问题确实是我遇到过的,当组件归属于应用程序时会出现这种情况。至于你的第三点,那绝对有道理,谢谢。如果您不介意,我已经编辑了问题以添加最初忘记的一点。 - Khorkhe
FastMM 不会报告由应用程序拥有的组件的泄漏,因为它将在终止时被销毁。但是,如果它是您的程序重复创建的对象,那么它仍然是一个泄漏,并且可能导致内存不足。我尝试在答案中解释这一点。当一个对象在终止时被销毁而不是在不再使用时被销毁时,仍然是一个泄漏,但经典泄漏检测工具无法检测到。 - David Heffernan
我撤销了你的编辑。那是完全不同的问题。请将其作为一个新问题提出。 - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接