C# 在字典中处理类时出现问题。尽管使用GC.Collect,但该类仍在堆内存中
我在字典里遇到了一个问题 这是我的密码C# 在字典中处理类时出现问题。尽管使用GC.Collect,但该类仍在堆内存中,c#,C#,我在字典里遇到了一个问题 这是我的密码 private Dictionary<string, MyProcessor> Processors = new Dictionary<string, MyProcessor>(); private void button1_Click(object sender, EventArgs e) { if (!Processors.ContainsKey(textBox1.T
private Dictionary<string, MyProcessor> Processors = new Dictionary<string, MyProcessor>();
private void button1_Click(object sender, EventArgs e)
{
if (!Processors.ContainsKey(textBox1.Text))
{
Processors.Add(textBox1.Text, new MyProcessor());
}
}
private void button2_Click(object sender, EventArgs e)
{
MyProcessor currnt_processor = Processors[textBox2.Text];
Processors.Remove(textBox2.Text);
currnt_processor.Dispose();
currnt_processor = null;
GC.Collect();
GC.WaitForFullGCComplete();
}
public class MyProcessor: IDisposable
{
private bool isDisposed = false;
string x = "";
public MyProcessor()
{
for (int i = 0; i < 20000; i++)
{
//this line only to increase the memory usage to know if the class is dispose or not
x = x + "gggggggggggg";
}
}
public void Dispose()
{
x=null;
this.Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
if (!this.isDisposed)
{
isDisposed = true;
this.Dispose();
}
}
~MyProcessor()
{
Dispose(false);
}
}
private Dictionary Processors=new Dictionary();
私有无效按钮1\u单击(对象发送者,事件参数e)
{
if(!Processors.ContainsKey(textBox1.Text))
{
Processors.Add(textBox1.Text,new MyProcessor());
}
}
私有无效按钮2\u单击(对象发送者,事件参数e)
{
MyProcessor current_processor=处理器[textBox2.Text];
处理器。删除(textBox2.Text);
当前处理器.Dispose();
当前处理器=空;
GC.Collect();
GC.WaitForFullGCComplete();
}
公共类MyProcessor:IDisposable
{
私有bool isDisposed=false;
字符串x=“”;
公共MyProcessor()
{
对于(int i=0;i<20000;i++)
{
//此行仅用于增加内存使用量,以了解该类是否为dispose
x=x+“gggggggggg”;
}
}
公共空间处置()
{
x=零;
这个。处置(真实);
总干事(本);
}
公共无效处置(bool处置)
{
如果(!this.isDisposed)
{
isDisposed=true;
这个。Dispose();
}
}
~MyProcessor()
{
处置(虚假);
}
}
我使用“ANTS内存分析器”来监视堆内存
只有当我从字典中删除所有键时,处理才会起作用
如何从堆内存中销毁该类
这是解决问题的视频链接
提前感谢我认为您看到了幽灵-请记住,.NET垃圾收集是基于内存压力的分代垃圾收集。如果没有内存压力,您的资源将不会被垃圾收集。调用
GC.Collect()
也是一个坏主意,我希望您这样做只是为了进行分析测试
另外,您在Dispose
方法中具体处理了哪些资源?看起来你不需要
在实现中,您没有提供任何
Dispose()
方法调用,也根本不需要终结器~MyProcessor()
。我认为您看到了重影-请记住,.NET垃圾收集是基于内存压力的分代垃圾收集。如果没有内存压力,您的资源将不会被垃圾收集。调用GC.Collect()
也是一个坏主意,我希望您这样做只是为了进行分析测试
另外,您在Dispose
方法中具体处理了哪些资源?看起来你不需要
在实现中,您没有提供单个
Dispose()
方法调用,也根本不需要终结器~MyProcessor()
。我想您可能需要调用GC.WaitForFullGCComplete();作为GC.Collect();只是启动GC
有可能存在引用泄漏(即您无意中将对对象的全部引用保留在某个列表中的某个位置,从而阻止了对象的收集)。我怀疑这本词典是否有这样一个“漏洞”,因为它是一个使用如此广泛的类,以至于它会成为一个已知的问题。最有可能的是,如果代码有问题,最有可能的问题是代码中的其他地方
如果这并没有给您带来实际的问题,请停止,拿起毛巾,不要惊慌,GC确实可以工作:)我想您可能需要调用GC.WaitForFullGCComplete();作为GC.Collect();只是启动GC 有可能存在引用泄漏(即您无意中将对对象的全部引用保留在某个列表中的某个位置,从而阻止了对象的收集)。我怀疑这本词典是否有这样一个“漏洞”,因为它是一个使用如此广泛的类,以至于它会成为一个已知的问题。最有可能的是,如果代码有问题,最有可能的问题是代码中的其他地方
如果这并没有给您带来实际的问题,那么停止它,拿起毛巾,不要惊慌,GC确实可以工作:)您正在从字典中删除具有一个名称的项,但处理具有另一个名称的项。所以,已处理的项仍然从字典中引用(Processors.Remove(textBox2.Text);而current=dict[textBox1.Text])
请注意Eric的评论-Dispose不会使对象为垃圾收集做好准备,如果它有引用,它仍将在内存中。您正在从字典中删除具有一个名称的项,但正在处理具有另一个名称的项。所以,已处理的项仍然从字典中引用(Processors.Remove(textBox2.Text);而current=dict[textBox1.Text])
请注意Eric的评论-Dispose不会使对象为垃圾收集做好准备,如果它有引用,它仍将在内存中。为什么要调用构造函数中的Dispose?此代码没有任何意义。这件事跟它有什么关系?你能解释一下为什么你认为拥有一个dispose方法会对内存管理产生任何影响吗?您是否错误地认为dispose用于管理内存?这是解决问题的视频链接,您为什么在构造函数中调用
this.dispose
?此代码没有任何意义。这件事跟它有什么关系?你能解释一下为什么你认为拥有一个dispose方法会对内存管理产生任何影响吗?您是否错误地认为dispose用于管理内存?这是问题的视频链接hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh。如果你没有一个r