【问题标题】:Memory Leak in TDictionary - Problems with Workaround?TDictionary 中的内存泄漏 - 解决方法有问题吗?
【发布时间】:2009-02-04 13:15:51
【问题描述】:

我刚刚考虑使用新的 TDictionary 类型。但在 QualityCentral 上,我读到了由 TDictionary 引起的两个内存泄漏:

http://qc.codegear.com/wc/qcmain.aspx?d=67355

我刚刚实现了建议的解决方法,基本上是子类化 TDictionary,覆盖析构函数并手动释放导致泄漏的两个对象:

destructor TMemCorrectedDictionary.Destroy;
begin
  Values.Free;
  Keys.Free;
  inherited;
end;

问题是,由于 Values 和 Keys 是 TDictionary 的只读属性,我不能将它们设置为 nil。好吧,为了清楚起见,现在一切正常,但我想知道如果 CodeGear 为泄漏发布补丁并在它们自己的析构函数中再次释放这两个对象会发生什么。这不会导致访问冲突吗?

提前感谢您的阅读(并希望能回答)。

【问题讨论】:

  • 感谢您的回答。尽管我真的不喜欢在释放对象后依靠其他人将所有对象设置为零的想法。还是我在这里偏执?
  • 我知道你的意思并同意。如果我是你,我会在热修复或服务包中解决此问题时再次查看源代码 - 只是为了确定。我希望尽快修复,因为 TDictionary 中还有其他严重的错误需要紧急修复。
  • 另外请注意,目前您应该避免使用 TDictionary,因为它的 Clear 方法中存在错误并且其添加性能很差。更多详情请看这里:alex.ciobanu.org/?p=59

标签: delphi memory-leaks delphi-2009


【解决方案1】:

您可以先调用inherited 并检查属性是否仍然设置:

destructor TMemCorrectedDictionary.Destroy;
begin
  inherited;
  Values.Free;
  Keys.Free;
end;

顺便说一句:Free 不关心要释放的实例是否为 nil,因此如果(但仅当)inherited Destroy 将属性设置为 nil,这将起作用。

【讨论】:

  • 这很危险,因为继承的将释放您之后引用的内存。只要 .Free 就可以了,因为它会自动检查 nil。
  • 我不明白。上面的代码只有在 CodeGear 提供了一个修复程序来释放变量 Values 和 Keys 并且之后不将它们设置为 nil 时才是危险的。但这是你能做的最好的。这绝对比释放它们而不将它们设置为 nil 并在之后调用继承要好。
【解决方案2】:

我不知道以前版本的 Delphi 怎么样,但在 XE5 中有一个 TObjectDictionary 类负责释放所有子项。

【讨论】:

  • 正如您在 QC 项目中看到的,该问题已在版本 12.0.3299.19016 中得到解决。这意味着 Delphi 2009 用户应该检查他们使用的构建(参见问题的标签)并且所有使用较新版本的用户都应该没问题。
【解决方案3】:

创建字典时使用此参数,它将释放对象。

TObjectDictionary<string, TMyClass>.Create([doOwnsValues]);

【讨论】:

    猜你喜欢
    • 2012-08-19
    • 2010-12-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    相关资源
    最近更新 更多