繁体   English   中英

Memory 泄漏,不确定是否管理 object

[英]Memory Leak, Unsure if object is managed

我遇到了 C# 中的 memory 泄漏问题。 当不应该创建新对象时,我看到进程管理器中的 memory 使用量增加了 10-20mb(甚至更多)。

q1) 我的印象是托管对象会被 GC 自动删除。 但是,当我使用 dotTrace 分析 memory 的使用情况时,我写的基本 object 似乎有 +10k 个实例(在显示新/死差异中)。 我发现如果这是 c++ 会泄漏的地方,

public void TriggerEvent(string tEvent)
{
    oVariable tVar = GetVar(tEvent);
    if (tVar != null)
        sVariableParser.TriggerEvent(tVar);
    else
    {            
        tVar = new oVariable("@CXZ_TEMP_VAR", tEvent, 0, this);
        tVar._BlockDependancies = true;
        sVariableParser.TriggerEvent(tVar);
    }
}

其中 oVariable 定义为

class oVariable : IComparable 

似乎 GC 没有删除新的 oVariables,我想知道我是否需要将 oVariable 实现为 IDisposable 并进行特定的系统调用以确保 GC 收集它? oVariable 中还有一些其他自定义对象,但我的印象是不使用任何外部对象(没有 COM 对象等)的简单对象应该被自动管理,或者我错了,我已经创建了非托管数据结构?

q2) Even with dotTrace Memory showing a lot of new oVariables where there should be zero (maybe the GC is lazy), I still have a feeling the memory leak could be coming from the windows forms, specifically DataGridViews. 我想知道是否有人可以告诉我在调用 DGV 更新/重绘后是否需要执行任何特定的 memory 释放

tGridView.Invoke(new UpdateGridViewCallBack(RedrawGlobalsViewGridView), tGridView);

我曾假设新的回调会自行清理。

首先,不要调用 GC.Collect() 它将强制进行垃圾收集,但有一些讨厌的副作用。 例如,它将所有未准备好进行垃圾收集的东西推回一代并延迟它的收集。 MS有关于世代等的信息

其次,GC 只会在没有引用的情况下收集对象。

因此,假设您的 sVariableParser 是一个成员变量,它包含对您的 tVar 的引用。 当 GC 运行时,它将看到 VariableParser 依赖于 tVar,而不是让它 go。

想象一下,你有这样的东西:

public class House
{
   public Person Resident1 {get; set;}
}

public class Person
{
   public string Name {get; set;}
}

然后在你的代码中你有

House.Resident1 = new Person {name = "John Calvin"};

当垃圾收集运行时,它无法清理与 Resident1 绑定的 Person object,直到 House 脱离 scope 并且不再使用。

所以这就是说,GC 会清理你的引用,但我猜你有一些代码保存在你的 tVar 上,而你没有意识到这一点。

首先,GC 不受任何人的直接控制,而是运行时的; 它只会在运行时认为它应该运行时运行。 这意味着计划进行清理的对象可能会持续数秒甚至数分钟,直到 memory 条件指示应执行清理。

但是,等待清理的 10,000 个死实例听起来像是 memory 泄漏。 需要检查的一些事项:

oVariable 是否包含或引用非托管或 IDisposable object? 如果是这样,oVariable 应该实现 IDisposable 并执行清理,释放对它不“拥有”的对象的引用,和/或处置它控制的对象。 您可以使用一种模式来避免显式调用 Dispose(); 看看http://www.codeproject.com/KB/cs/idisposable.aspx

oVariable 是否订阅其他对象的任何事件? As long as the object with the event is in memory, any oVariable that has added its handler to the event will remain in memory, because the reference to the method will keep the object "alive" as far as GC is concerned. 同样,您应该创建一个 IDisposable 实现并让 object 从它侦听的任何事件中删除自己。

最后,我在您对另一篇文章的评论中注意到,您与其他 oVariables 保持向上和向下的层次关系。 只要 oVariable 在任何这些列表中,它就会被引用。 我会三重检查所有在这些列表中添加和删除实例的代码; 您忘记在某处删除对象,因此它们会无限期地徘徊。 同样,处理 oVariable 应涉及 (1) 从任何/所有 Master oVariables 中删除对变量作为 Slave 的任何引用,(2) 从任何/所有 Slave 中删除对作为 Master 的变量的任何引用,最后 ( 3) 清除变量的主从列表。 只有当 object 在 memory 中完全“孤立”时,GC 才会销毁它。

oVariable的内部实现是什么样的? 如果您正在使用任何继承IDisposable的资产,则需要关闭它们(或使用using块)以确保它们被正确处置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM