C#线程不释放内存

时间:2011-06-13 13:54:59

标签: c# multithreading memory-management

我有一个用C#.Net编写的Windows服务。当服务启动时,我会生成一个新线程,如下所示

new Thread(new ThreadStart(Function1)).Start();

此线程无限循环并执行我的服务所需的职责。每天一次,我需要同时执行一个不同的操作,我的线程会生成第二个线程,如下所示

new Thread(new ThreadStart(Function2)).Start(); 

这第二个线程执行一个非常简单的功能。它使用FileReadAllLines读取文本文件的所有行,快速处理此信息并退出。

我的问题是没有收集读取文件的第二个线程使用的内存。我让我的服务运行了3个小时,希望GC会被调用但没有任何反应,任务管理器仍然显示我的服务正在使用150mb的内存。读取和处理文本文件的功能非常简单,我确信没有对包含文本的字符串数组的隐藏引用。有人可以解释为什么会这样吗?是否有可能由另一个衍生线程生成的线程自身无法清理?

谢谢

2 个答案:

答案 0 :(得分:11)

相信垃圾收集器并停止担心。 150兆是没有。你甚至没有测量文件的大小;大部分都是代码。

如果您担心内存的来源,首先要了解内存在现代操作系统中的工作原理。在开始抛出诸如“150兆的已分配内存”之类的数字之前,您需要了解虚拟和物理内存之间的差异,已提交和已分配内存之间的差异以及所有这些内容。请记住,在3​​2位进程中有2000兆的虚拟地址空间;我不认为150兆的过程无论如何都很大。

像Jon说的那样,你想要关注的是私有字节的缓慢稳定上升。如果没有发生,那么你没有内存泄漏。让垃圾收集器完成它的工作而不用担心它。

如果你 仍然担心它,天堂就不会使用任务管理器。获取内存分析器并了解如何使用它。任务经理通过从30000英尺俯视它们来检查过程。您需要使用显微镜而不是望远镜来分析过程如何释放单个文件的字节。

答案 1 :(得分:5)

如果您正在使用Windows任务管理器尝试计算出使用的内存,则可能会欺骗您。据我所知,CLR使用的内存通常不会返回给操作系统...所以你可能仍会看到一个高工作集,即使大部分内存仍然可以在内部重用这个过程。

如果您让服务运行一周,您是否看到内存使用量在整个星期内稳步攀升,或者它是否仅在第一天增加,然后是高原?如果是这样,你肯定认为这是一个问题吗?如果是这样,您可能需要将第二个任务放在一个单独的过程中。