线程委托内存泄漏的问题

sdpdww 2015-11-01 01:21:17
第一段代码 ,存在问题,内存一直呈8k增长,进程句柄一直在增长。
delegate void aa(string s);//创建一个代理
private void pri(string t)//这个就是我们的函数,我们把要对控件进行的操作放在这里
{
if (!label1.InvokeRequired)
{
richTextBox1.Text =t;
}
else
{
aa a1 =new aa(pri);
Invoke(a1,new object []{t});
}
}

private void Form1_Load(object sender, System.EventArgse)
{
Thread newthread = new Thread(new ThreadStart(ttread));
newthread.Start();
}
void ttread()
{
while(true)
{
pri("sdfs");
}

}


第二段代码 ,遇到的问题,内存还是一直增长,但是句柄数正常,没有增长。
System.Timers.Timer t = new System.Timers.Timer(2000);

private void Form1_Load(object sender, EventArgs e)
{
t.Elapsed += new System.Timers.ElapsedEventHandler(Timer_TimesUp);
t.AutoReset = false;
}

int ncount = 0;
private void UpdateUI(string str)
{

ncount++;
this.label1.Text = ncount.ToString();
}



public delegate void MyInvoke(string str);
private void Timer_TimesUp(object sender, System.Timers.ElapsedEventArgs e)
{

t.Stop();
MyInvoke mi = new MyInvoke(this.UpdateUI);

this.BeginInvoke(mi, new object[] { "" });
t.Start();

}



两段代码其实都是在一直执行任务,但是这两段代码,其实都是只是在界面上显示简单的信息,但是为何会一直内存和句柄泄漏呢?是c#本身机制的问题?还是说增长到一定程度,c#会自动回收?
如果能修改,应该怎么改呢?
...全文
287 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
veryshy 2017-03-16
  • 打赏
  • 举报
回复
把new移到外面也不行,是invoke导致的内存泄漏,我试过,把委托写道外面,然后只执行invoke,依然不行
veryshy 2017-03-16
  • 打赏
  • 举报
回复
把new移到外面也不行,是invoke导致的内存泄漏,我试过,把委托写道外面,然后只执行invoke,依然不行
winnowc 2015-11-02
  • 打赏
  • 举报
回复
引用 5 楼 sdpdww 的回复:
原来做c++的,现在用csharp做很多不熟悉地地方。我上面德代码,能否帮我改一下。还有你说不存在内存泄露,但是为何一直增长呢?在c++里new了要delete,csharp里没有,所以一看到内存持续增长,就害怕长时间运行会出问题。 麻烦帮我把代码改一下吧,非常感谢。
.net 这托管环境就是让你不用操心delete,GC 帮你管理内存来提高生产力。然而 GC 什么时候进行回收不是你控制的(一般也不应该控制)。从c++过来需要适应下,手动驾驶的车变成自动驾驶了,是不是反而不放心了,觉得总会出事。 你需要的不是让那段代码的内存不增长,而是运行足够长的时间,看看能增长到多少。并不是看到增长就是内存泄漏。带 GC 的环境的内存占用基本都是锯齿状的,慢慢增长,GC 后回落,再慢慢增长,GC后再回落,和 c++ 程序不是一个模式的。
事理 2015-11-01
  • 打赏
  • 举报
回复
用这个通用的吧,测试过没有出现这种问题。 http://www.cnblogs.com/slyzly/articles/2121436.html
sdpdww 2015-11-01
  • 打赏
  • 举报
回复
引用 4楼winnowc 的回复:
这两种都不存在内存泄漏,第二种句柄没变化是因为用了 BeginInvoke 而不是 Invoke,Control上的 Invoke 是相当低效的实现,内部使用了 ManualResetEvent,它就是增长的那个句柄。 重复的创建 Delegate 和 new object[] 是内存增长的主因,不过一般这都不是问题,而且并不容易检查(比如如果参数需要int 转换object传递,这种装箱也要占用内存)。不嫌麻烦可以都放外面创建一次。如果你用 Resharper,它有个插件叫 Heap Allocations Viewer,可以方便检查这些内存分配。 因为GC机制,想确定有没有内存泄漏需要完全GC才能判断。你可以用一个按钮或者定时调用下面的代码再看结果(不过GC本身也要占用内存,如果第一次GC前内存占用并不大,GC之后反而可能变大哦):

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
原来做c++的,现在用csharp做很多不熟悉地地方。我上面德代码,能否帮我改一下。还有你说不存在内存泄露,但是为何一直增长呢?在c++里new了要delete,csharp里没有,所以一看到内存持续增长,就害怕长时间运行会出问题。 麻烦帮我把代码改一下吧,非常感谢。
winnowc 2015-11-01
  • 打赏
  • 举报
回复
这两种都不存在内存泄漏,第二种句柄没变化是因为用了 BeginInvoke 而不是 Invoke,Control上的 Invoke 是相当低效的实现,内部使用了 ManualResetEvent,它就是增长的那个句柄。 重复的创建 Delegate 和 new object[] 是内存增长的主因,不过一般这都不是问题,而且并不容易检查(比如如果参数需要int 转换object传递,这种装箱也要占用内存)。不嫌麻烦可以都放外面创建一次。如果你用 Resharper,它有个插件叫 Heap Allocations Viewer,可以方便检查这些内存分配。 因为GC机制,想确定有没有内存泄漏需要完全GC才能判断。你可以用一个按钮或者定时调用下面的代码再看结果(不过GC本身也要占用内存,如果第一次GC前内存占用并不大,GC之后反而可能变大哦):

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
sdpdww 2015-11-01
  • 打赏
  • 举报
回复
引用 2楼ajianchina 的回复:
第一段 aa a1 =new aa(pri); 第二段 MyInvoke mi = new MyInvoke(this.UpdateUI); 移到外面,不要一直new出新对象 还有,你第一段代码运行的时候ui会感觉到卡吗?
卡不卡倒是能解决,你的意思是因为反复new的原因?
ajianchina 2015-11-01
  • 打赏
  • 举报
回复
第一段 aa a1 =new aa(pri); 第二段 MyInvoke mi = new MyInvoke(this.UpdateUI); 移到外面,不要一直new出新对象 还有,你第一段代码运行的时候ui会感觉到卡吗?
sdpdww 2015-11-01
  • 打赏
  • 举报
回复
自己顶一下,希望高手能看到。

111,092

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧