首页 新闻 会员 周边

c#如何查看内存占用?求调试方法?求调试方法?

0
悬赏园豆:50 [已解决问题] 解决于 2013-12-03 12:46

我写了一个程序,单线程运行时内存非常正常,多线程运行不到半小时,内存就从80M升至900多M,经多天调试毫无进展,因为每次运行到进程内存接近1G时会报内存溢出的错误,错误语句比较随机,有时只是一个int变量分配,请问是否有办法查看是哪些资源没有释放?

 

求调试方法?

问题补充:

以下是我的代码的伪代码结构,MyTask为我自定义线程包装类,此类内部会开一个线程执行TaskProc,代码运行可能需要一个月时间,所以内存问题非常重要:

var task = new MyTask();

task.Start(null);

void TaskProc() 

{

  ...

  foreach(var p in params)

  {

    var innerTask = new MyTask();

    innerTask.Start(p);

    while(innerTask.IsRunning)  //等待innerTask运行结束

      Thread.Sleep(1000);

  }

  ...

}

MyTask无递归调用,只有这两层。

空明流光的主页 空明流光 | 初学一级 | 园豆:106
提问于:2013-12-01 12:09
< >
分享
最佳答案
0

首先看下你的程序中有多少个线程,本身每个线程就要占1m内存的,线程多了程序肯定挂。

至于对象的内存占用,Visual Studio自己就带memory profile工具,从分析菜单里就可以进去。也有一些第三方的memory profile工具做得不错的:http://memprofiler.com/ 。

另外,MS还提供了一个CLR Profiler,要精简得多,在不方便使用这些大型调试工具的地使用也很方便的。

收获园豆:50
天方 | 大侠五级 |园豆:5407 | 2013-12-01 12:39

我下了个,memory profile 4.6,但这个工具使用真是复杂,看了大半天,看不懂啊,我要疯了

空明流光 | 园豆:106 (初学一级) | 2013-12-02 15:52

@沧海一杰: 在内存达到1G时我抓到一个快照,共8个线程,4个alive的,我觉得也算正常。占用内存最大的字符串类型,其中最大占用空间最大的字符串实例都是指向下面这个方法:

public static string GetWebBrowserSourceCode(WebBrowser browser)
        {
            if (browser.Document == null)
                return string.Empty;

            if (browser.Document.DomDocument == null)
                return string.Empty;

            var document = (browser.Document.DomDocument as mshtml.HTMLDocumentClass);
            if (document != null && document.documentElement != null)
                return document.documentElement.outerHTML ?? string.Empty;
            else
                return string.Empty;
        }

这个方法有问题吗?会导致内存不被释放吗?

空明流光 | 园豆:106 (初学一级) | 2013-12-02 16:28

@沧海一杰: w从这些数据能否看出是托管泄漏还是非托管泄漏?我的程序同时应该只有两个线程运行,单线程包括UI线程占了80M,两个正常应该在200M下,但实际上最终却涨到了超过1G而导致内存溢出。

空明流光 | 园豆:106 (初学一级) | 2013-12-02 17:12
其他回答(3)
0

我以前也遇到你的类似问题,仅看你提供的伪代码看不出问题,你的问题无非是线程太多(可能有你未察觉的潜在线程),资源释放有问题,这类问题的解决除了经验外,需要艰苦细致的工作,成本有时会很高。可以加QQ:1561724180探讨。

LiuKaiFa | 园豆:1491 (小虾三级) | 2013-12-01 13:07

大神再给出出主意吧

支持(0) 反对(0) 空明流光 | 园豆:106 (初学一级) | 2013-12-02 17:25
0

问题可能出在MyTask,如果方便的话,建议贴出MyTask的实现代码

dudu | 园豆:30979 (高人七级) | 2013-12-01 13:38

贴出代码可能不太方便,一是太多,二是需要保密一部分东西。

支持(0) 反对(0) 空明流光 | 园豆:106 (初学一级) | 2013-12-02 16:28

@沧海一杰: 大神再给出出主意吧

支持(0) 反对(0) 空明流光 | 园豆:106 (初学一级) | 2013-12-02 17:25
0

问题已经解决,谢谢各位。原因如上面我的伪代码所定,这种结构有问题。虽然宿主线程在Sleep,但线程中有事件被UI线程订阅,其它过程仍然会导致线程内其它方法运行,导致很多资源没有释放。这种结构实际上只有一个线程在同时运行,所以改成单线程递归调用就很正常了,测试了很久,暂时没有发现内存泄漏的迹象了。

空明流光 | 园豆:106 (初学一级) | 2013-12-03 12:46
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册