在长时间运行的Mono / C#应用程序中调试内存泄漏

时间:2018-06-30 12:05:57

标签: c# mono

我有一个C#程序,它使用mono 5.10在Ubuntu VM上作为服务器运行。程序不时地开始使用大量内存,直到最终崩溃。这样的内存泄漏通常可能需要几天的时间,而且我无法在本地重现该问题。

在过去的几天中,我使用了mono日志分析器来按需收集堆快照。这给了我15Gb以上的文件。我设法从发生内存泄漏时获得了一个堆快照,在Xamarin分析器中显示如下:

HeapShot summary in the Xamarin profiler

运行mprof-report会给出类似的无益报告。

都没有真正帮助调试问题。显然,线程池中发生了一些事情,但是似乎没有办法弄清楚是什么。

能够查看对象的分配位置可能会有所帮助,但这需要在事件探查器中启用alloc,由于它将产生的文件大小,这是不可能的。

是什么原因导致大量IThreadPoolWorkItem出现?该应用正在使用30-40%的CPU,因此看来任务调度的速度似乎没有CPU可以处理的快。

是否可以列出ThreadPool作业引用的对象?至少这将使我能够确定正在运行的代码段是如此之多。据我所知,mprof-report仅显示了反向引用,这并不是很有用,因为IThreadPoolWorkItem显然是ThreadPool所拥有。

更新:任务不受(磁盘)IO约束。泄漏时,读取速度为每秒10 kbs,这不会使磁盘饱和。

再三考虑:如果计划了很多任务,我是否也应该不会看到很多单独的IThreadPoolWorkItem对象?由于IThreadPoolWorkItem不是结构,因此应该为实际对象提供一个单独的条目,而IThreadPoolWorkItem[]只是一个指针数组。因此,这表明这些IThreadPoolWorkItem[]只是(主要是)null个指针的数组。

更新ThreadPool.GetAvailableThreads显示2个工作线程和0个完成端口线程处于活动状态,这似乎表明ThreadPool做得很好。自定义日志记录还表明,我又没有计划太多任务,而计划的任务很快就完成了。

0 个答案:

没有答案