C# 什么会导致应用程序的RAM使用量呈线性增长?

C# 什么会导致应用程序的RAM使用量呈线性增长?,c#,performance,C#,Performance,形势 我创造了一个怪物。Applikentstein是一个RAM杀手,我仍然不能完全清楚地理解它是如何以及为什么看起来如此无赖的。基本上,它是一个计算应用程序,为N个场景启动测试组合。每个测试都在一个单独的专用线程中进行,包括读取大型二进制数据,对其进行处理,并将结果放到数据库中。 数据首先在读取时放入缓冲队列(~100MB),然后在处理时在流上退出队列。在处理过程中,数据块被跟踪到数组中。对于线程,我有一个包含N个工作线程的工作线程缓冲队列,每次一个工作线程完成并死亡时,都会通过队列启动一个新

形势
我创造了一个怪物。Applikentstein是一个RAM杀手,我仍然不能完全清楚地理解它是如何以及为什么看起来如此无赖的。基本上,它是一个计算应用程序,为N个场景启动测试组合。每个测试都在一个单独的专用线程中进行,包括读取大型二进制数据,对其进行处理,并将结果放到数据库中。 数据首先在读取时放入缓冲队列(~100MB),然后在处理时在流上退出队列。在处理过程中,数据块被跟踪到数组中。对于线程,我有一个包含N个工作线程的工作线程缓冲队列,每次一个工作线程完成并死亡时,都会通过队列启动一个新的工作线程缓冲队列

下面是如果我启动太多线程(“太多”取决于系统RAM)会发生什么情况
问题是RAM使用率斜率在某个点上并没有变平,它只是不断增长,然后不时下降(一些线程完成,GC进行整理),但一旦启动新线程,它就会反弹,随着时间的推移越来越高(可能在这里泄漏)

随着时间的推移,我问了一个又一个问题。 现在是我感觉的时候了,我对这件事了解的越多,我真正理解的就越少。(叹气)

问题
现在,我想对.Net下的内存管理有一个清晰的解释/参考资料<我知道有很多关于这个广泛话题的文学/博客文章。但是这个话题太大了,我真的不知道从哪里开始,而不会失去我自己(和我公司的宝贵时间)。我想保持专注和目标导向

第二个,当我试图在实验室条件下模拟/再现上面的陡坡(由“公羊龙”怪物“自然”创建)时,出现了“倾斜”,以隔离这种行为并找到解决方法(即监控进程使用的内存,并通过停止任何新线程创建,将其限制在总内存的X%)
为什么在实验室条件下(使用一些消耗内存的多线程循环)复制我的流氓程序看起来这么容易(在任务管理器中将RAM放在膝盖上)是如此困难?GC似乎定期清理原型中的内容,而我的应用程序似乎将大量引用的内容保存到RAM中。为什么

第三个难题是缓存的工作方式:为什么firefox使用高达1GB的内存和缓存,而我的应用程序只会破坏RAM?运行中的线程是否可能大量/频繁地使用数据,从而永远不会缓存数据

跟踪和引导
我已经使用了VS profiler,并发现了一些瓶颈(大数组排序)、GCRoot和WinDBG控制台。每次我都会截取更多的漏洞并修复其中的一些漏洞(或多或少,比如缺少事件取消订阅等等…)


我知道我对记忆的一些基本概念的理解仍然很差,这是事实。这就是为什么我要在这里寻找线索。我准备阅读一些有意义的资源,了解更多,并遵循一些开明的建议

与其说是答案,不如说是观察:

有太多不同的事情可能会影响这一切,这并不好笑。您描述的系统听起来好像有数百种不同的东西需要检查/观看

首先也是最重要的一点是要跟踪您的每一个内存泄漏。你已经开始了,但我建议你继续

关于firefox和“缓存”的一个注意事项。你说的是windows分页文件;windows控制着这一点。关于何时将数据分页到磁盘以释放RAM,它有自己的规则。我认为这是一种转移注意力的做法,你不想走这条路。数据被分页到磁盘的一个原因是缺少使用。在firefox和其他应用程序中,这种情况非常普遍;根据您的描述,您的软件不是这样运行的

我将研究循环有多紧,以及是否给了.net运行时执行清理的机会。看起来它是在使用上强制问题,所以这可能是正常的

不管怎样,我都不明白到底是什么问题。您提到该图是启动太多线程的结果。。好的,这是意料之中的。您启动的每个线程都将占用资源;大量发射它们自然会占用大量资源。。。在某个时刻,系统将无法启动更多,并将级联失效

影响实验室与生产系统的一些问题:不同的修补程序级别windows/.net/等,不同的操作系统(例如2008与2008 R2是一个巨大的差异),不同的CPU和/或内存配置。你所付出的真的很难说

为了重现一个事件,您需要有完全匹配的硬件和软件。然后,您将需要相同的输入。如果其中任何一个都关闭了,那么你就可以接近它了。首先要做的是确保所有加载的和输入是相同的。这些很容易控制。然后开始玩


稍有更新。我读了你列出的一些问题

为了确定系统的最佳线程数,必须在目标硬件/软件上进行配置。最好是在系统本身上。要做到这一点,需要相当多的人手。实现自动化的唯一方法是有一个看门狗,它可以测试事物是如何运行的,并根据故障率增加或减少线程。有点像一些狂热的计算机现在可以自动超频:不断加热直到东西融化;然后后退1位

当然,如果某些百分比