C# 内存泄漏,不确定对象是否被管理

C# 内存泄漏,不确定对象是否被管理,c#,garbage-collection,C#,Garbage Collection,我在C#中遇到内存泄漏问题。我看到当不应该创建新对象时,process manager中的内存使用量增加了10-20mb(甚至更多) q1)我的印象是,GC将自动删除托管对象。但是,当我使用dotTrace分析内存使用情况时,我编写的一个基本对象似乎有+10k个实例(在show new/dead differences中)。我发现如果C++,会漏水的地方 public void TriggerEvent(string tEvent) { oVariable tVar = GetVar(t

我在C#中遇到内存泄漏问题。我看到当不应该创建新对象时,process manager中的内存使用量增加了10-20mb(甚至更多)

q1)我的印象是,GC将自动删除托管对象。但是,当我使用dotTrace分析内存使用情况时,我编写的一个基本对象似乎有+10k个实例(在show new/dead differences中)。我发现如果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);
    }
}
其中卵巢的定义为

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

问题2)即使dotTrace内存显示了许多新的数据,其中应该是零(可能GC是懒惰的),我仍然感觉内存泄漏可能来自windows窗体,特别是DataGridView。我想知道是否有人能告诉我,在使用

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

我原以为新的回拨电话会自行清理

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

首先,不要调用GC.Collect(),它将强制垃圾收集,但会产生一些恶劣的副作用。例如,它会将所有未准备好进行垃圾收集的内容推回到一代人,并延迟垃圾收集。MS有信息等

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

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

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

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对象,直到House超出范围且不再使用


所以所有这些都是说,GC将清理您的引用,但我猜您的tVar中有一些代码,您没有意识到这一点。

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

然而,10000个等待清理的死实例听起来像是内存泄漏。一些需要检查的事项:

Ovorable是否包含或引用非托管或IDisposable对象?如果是这样,Ovorable应该实现IDisposable并执行清理,释放对它不“拥有”的对象的引用,和/或处理它确实控制的对象。有一种模式可以用来避免显式调用Dispose();看

Ovorable是否订阅其他对象的任何事件?只要带有事件的对象在内存中,任何已将其处理程序添加到事件的对象都将保留在内存中,因为对该方法的引用将使该对象在GC方面保持“活动”。同样,您应该创建一个IDisposable实现,并让对象从它侦听的任何事件中删除自己


最后,我注意到在你对另一篇文章的评论中,你与其他人保持着上下的等级关系。只要Ovorable在这些列表中,它就会被引用。我将对所有从这些列表中添加和删除实例的代码进行三重检查;你忘了在某处移除对象,所以它们会无限期地挂在那里。同样,处理一个子午表应该包括(1)从任何/所有主子午表中删除对变量作为从变量的任何引用,(2)从任何/所有从变量中删除对变量作为主变量的任何引用,最后(3)清除变量的主列表和从列表。只有当对象在内存中完全“孤立”后,GC才会销毁它。

可删除的
构造函数在做什么?(顺便说一句,你在类型中使用大写名称对每个人都有好处,其他任何事情都会造成混乱)TName是Delphi和其他一些语言中类型名称的标准名称,但它非常过时。
tEvent
是什么,
TriggerEvent
方法有什么作用?@David,我不确定是从哪里学来的,但是我通常用o作为对象的前缀,用s作为静态的前缀,用e作为枚举的前缀,用t作为临时变量(函数的局部变量),直到最近,用m作为成员的前缀。这在业界会被认为是不好的形式吗(在我开始申请工作之前我应该停止吗)?@David Lively:对于变量名,您的命名约定很好,但是.NET中的实际类型名应该是大写的(例如
表单
按钮
颜色
等)。实现相当简单(此处粘贴有点太长了),唯一不是基本字符串/布尔等的成员是private-List-Slaves=new-List();private-List-Masters=new-List();,我不认为这会阻止它被GC’d?在dotTrace中看到+10k的对象是内存泄漏的迹象,还是GC长时间(+30分钟)不能收集?我几乎100%确定没有任何东西开始引用新创建的Ovorable,所以我认为这不是问题所在。嗯…
List
不会这样做。你能用剩下的方法更新你的帖子吗?还有,GC r