C# 线程+委托 内存泄漏的问题

武烈 2018-04-27 02:53:42
内存一直不断增长,进程句柄一直在增长
delegate void aa(string s);//创建一个代理
aa a1 =new aa(pri);

private void pri(string t)//这个就是我们的函数,我们把要对控件进行的操作放在这里
{
if (!label1.InvokeRequired)
{
richTextBox1.Text =t;
}
else
{
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");
}

}



发现只要使用invoke或begininvoke内存就会一直增加,请各位大神指导
...全文
1393 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2018-04-28
  • 打赏
  • 举报
回复
这条,以及上面所有的帖子都已经说了。while(true)的问题。 我不知道楼主最后说的
引用 17 楼 u013425590 的回复:
无论是线程+委托,还是事件加委托都会让内存不断增加,各位可以跑2h以上,然后查看一下内存。对了,win7上会出现这种问题,win10内存不会增加,但cpu使用率会增大很多。使用GC不起作用,各位可以试试
是不用while(true)测试出来的结果吗? 如果还是while(true),那就真没必要说下去。
正怒月神 2018-04-28
  • 打赏
  • 举报
回复
引用 17 楼 u013425590 的回复:
无论是线程+委托,还是事件加委托都会让内存不断增加,各位可以跑2h以上,然后查看一下内存。对了,win7上会出现这种问题,win10内存不会增加,但cpu使用率会增大很多。使用GC不起作用,各位可以试试
其实我重点说的是 使用 事件通知来替代你的 while(true) gc回收,本来就是不靠谱的。
武烈 2018-04-28
  • 打赏
  • 举报
回复
无论是线程+委托,还是事件加委托都会让内存不断增加,各位可以跑2h以上,然后查看一下内存。对了,win7上会出现这种问题,win10内存不会增加,但cpu使用率会增大很多。使用GC不起作用,各位可以试试
牧歌ing 2018-04-28
  • 打赏
  • 举报
回复
while(true)没跳出,应该不会释放内存,你可以在while(true)里面用GC试试。
正怒月神 2018-04-28
  • 打赏
  • 举报
回复
既然楼主会使用委托, 那么就可以使用事件通知刷新, 而不是 while(true)来刷新前台ui。 这个问题其实也没有太特别的,就是while(true)的问题了。
Anonymous477 2018-04-28
  • 打赏
  • 举报
回复
期待楼主最终的研究结果

  • 打赏
  • 举报
回复
引用 31 楼 u013425590 的回复:
不行,内存还是在增长,不过比之前缓慢些
你先看看回收不回收吧,我在本地用,内存在一定程度会自动回收。 如果你这边出现不回收,建议你在using中定义新的全套数据读取变量,然后在using中赋值这套变量。不要在using中直接使用用静态和公用变量。 还有就是你这个古怪的委托为啥那个richtextbox并没有委托??? 建议你把代码一点一点排除去做,不要看到一点就改上去,最后可能错误的位置你一辈子都分析不出来。
武烈 2018-04-28
  • 打赏
  • 举报
回复
不行,内存还是在增长,不过比之前缓慢些
吹风的兔子 2018-04-28
  • 打赏
  • 举报
回复

刚才 忘了传自己的 代码分析图。
吹风的兔子 2018-04-28
  • 打赏
  • 举报
回复
修改为 如下函数,问题基本就能解决【没有测试,但是,我就是这么自信】

       private void  pri(string t)//这个就是我们的函数,我们把要对控件进行的操作放在这里
       {
           if  (!label1.InvokeRequired)
           {
               richTextBox1.Text =t;
           }
           else
           {
               //直接用 lamada 代码反而清晰不少。
               Invoke((ThreadStart)(()=>{
                   richTextBox1.Text =t;
               }));
           }
       }

吹风的兔子 2018-04-28
  • 打赏
  • 举报
回复
我又分析了一下:我突然有点心虚 了 —— 我觉得,我会打自己脸。
  • 打赏
  • 举报
回复
还有就是10ms的刷新肉眼不可见,建议刷新在300ms就行了,跟32帧电影差不多意思。
  • 打赏
  • 举报
回复

        void ttread()
       {
             while(true)
              {
                  using (Font font2 = new Font("Arial", 10.0f))
                  {
                      this.listBox1.BeginInvoke(new Action(() => { this.listBox1.BackColor = Color.Bisque; }));
                      System.Threading.Thread.Sleep(500);
                  }
               }
         }
看看还不停的涨吗? 顺便吐槽一下娘的用个using非要有实现System.IDisposable接口的对象确实有点古怪。 我本地测试是资源是会正常回收的。
武烈 2018-04-28
  • 打赏
  • 举报
回复
特别说明一下,是不断的刷新界面数据,间隔10ms
  • 打赏
  • 举报
回复
引用 21 楼 u013425590 的回复:
各位总是认为while导致内存耗尽,我刚才花了2h,使用事件+委托来刷新界面,然后内存同样不断增加,最后撑爆了!所以,各位,如果有兴趣先试试再说吧
发代码吧,你回收没做好。
武烈 2018-04-28
  • 打赏
  • 举报
回复
我觉得应该换种思路来解决这种问题,我现在想实现一个功能,在子线程中刷新界面!如果各位实现这个功能,并且内存还没增加,我觉得我的问题就解决了
武烈 2018-04-28
  • 打赏
  • 举报
回复
各位总是认为while导致内存耗尽,我刚才花了2h,使用事件+委托来刷新界面,然后内存同样不断增加,最后撑爆了!所以,各位,如果有兴趣先试试再说吧
武烈 2018-04-28
  • 打赏
  • 举报
回复
或者这样说吧!我现在需要在线程中不断解析数据,然后在界面上显示,如果不用线程+委托或者事件+委托的方法来刷新界面,应该用什么方法来做?各位可以自己试试,跑个2h,看看我说的现象是否会出现。我想这样更有说服性
  • 打赏
  • 举报
回复
跟委托关系不大的,委托只是一种不自动回收的类型罢了,你可以试试别的更直接的类型,比如Array。

        void ttread()
       {
             while(true)
              {
                  long[] arr = new long[9999999];
                  for (int i = 0; i < 9999999; i++)
                  {
                      arr[i] = long.MaxValue - (new Random()).Next(int.MaxValue);
                  }
               }
         }
你可以试试这样,内存耗尽的更快。还能看到更直接的小阶梯,增大数组的长度你可以看到更直接的内存增加。 至于你说的windows不同版本之间内存占用的区别,你打开虚拟内存占用就会发现,只是系统将不用的内存缓存硬盘的机制变化罢了。
xuzuning 2018-04-27
  • 打赏
  • 举报
回复
而 内存泄露 的本意是突破了受管辖的内存边界
加载更多回复(12)

110,536

社区成员

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

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

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