场合
我创造了一个怪物。 Applikentstein是一个RAM杀手,我仍然无法清楚地了解如何以及为什么它如此流氓设计显得如此诡异。基本上,它是一个计算应用程序,为N场景启动测试组合。每个测试都在一个专用线程中进行,包括读取大型二进制数据,处理它并将结果丢弃到DB。
数据在被读取时首先被放入缓冲队列(~100MB),并在处理流时在流上出列。在处理期间,数据块被跟踪到阵列中。从线程开始,我有一个带有N个工作者的工作缓冲队列,每次完成并死亡,新的一个通过队列启动。
如果我启动太多线程(“太多”,具体取决于系统RAM),下面会发生什么情况 问题是RAM使用率斜率在某些时候不会变平,它会不时地增长,然后逐渐下降(一些线程完成,GC执行其内务处理),但是一旦新线程被启动它就会反弹随着时间的推移越来越高(可能在这里泄漏)
随着时间的推移,我提出了this个问题,that一个问题,this另一个问题。 现在是我感觉到的时间,我越了解这一点,我真正理解的越少。 (叹气)
问题
现在,我希望有一个关于完全如何在.Net下管理的内存的清晰解释/资源。我知道有很多关于这个广泛主题的文章/博客文章。但是主题是如此之大,我真的不知道从哪里开始而不会失去自己(以及我公司的宝贵时间)。我希望保持专注和客观导向。
第二次,当我试图在实验室条件下模拟/重现上面的陡坡(由RAM'osaurus Monster“自然地”创建)时,出现了“倾斜”,以便隔离这种行为找到它的治疗方法(即监视进程使用的内存,并通过停止任何新的线程创建将其限制为总内存的X%)。
为什么在实验室条件下(有一些内存消耗多线程循环)很难重现我的流氓程序似乎很容易这么做(在任务管理器中让RAM瘫痪)? GC似乎在原型中定期清理内容,而我的应用程序似乎将大量引用的内容保存到RAM中。怎么会 ?
第三个令人费解的是缓存工作的方式:为什么firefox使用高达1 Gb内存并使用缓存,而我的应用程序只是吹了RAM?运行的线程是否可能大量/频繁地使用数据,因此它永远不会被缓存?
曲目和线索
我已经使用了VS分析器并发现了一些瓶颈(大型阵列分类),使用了GCRoot和WinDBG控制台。每次我狙击进一步泄漏并修复其中一些(或多或少,如缺乏事件取消订阅等等)
我知道我对一些关于记忆的基本概念的理解仍然很差,这是事实。这就是我在这里要求领先的原因。我准备阅读合理的资源并了解更多信息,并遵循一些开明的建议。
答案 0 :(得分:2)
与观察结果不一样的答案:
有很多不同的东西可能影响到这一点,这并不好笑。您描述的系统听起来像是需要检查/观看的数百种不同的东西。
其中最重要的是跟踪你所遇到的每一次内存泄漏。哪,你已经开始了,但我建议你只需继续前进。
关于firefox和“缓存”的一个注释。你在谈论Windows分页文件; Windows控制这个。关于何时将数据分页到磁盘以释放RAM,它有自己的规则。我建议这是一个红鲱鱼,你不想走那条路。数据被分页到磁盘的一个原因是缺乏使用。使用firefox和其他应用程序这很常见;根据您的描述,您的软件不会像这样。
我会研究你的循环有多紧,以及你是否给.net运行时提供了执行清理的机会。看起来它正在强制使用问题,所以这可能没问题。
无论哪种方式,我都不明白究竟是什么问题。你提到图表是启动太多线程的结果。好的,这是预期的。你发布的每个线程都会占用资源;发射大量的它们本质上会使用大量的资源......在某些时候,系统将无法启动更多,它将级联成失败。
影响您的实验室与生产系统的一些问题:不同的补丁级别windows / .net / etc,不同的操作系统(例如2008与2008 R2之间存在巨大差异),不同的CPU和/或内存配置。对你所给予的东西一无所知。
要重现事件,您需要具有完全匹配的硬件和软件。然后你需要相同的输入。如果其中任何一个关闭,那么可能能够接近。首先要做的是确保所有加载和输入都相同。那些很容易控制。然后开始玩。
轻微更新。我读了你列出的一些问题。
要确定系统的最佳线程数,必须在目标硬件/软件上进行配置。最好是在系统本身。这需要花费相当多的时间才能达到目的。自动化它的唯一方法是使用监视程序来测试事物的运行方式,并根据故障率增加线程或减少。有点像许多发烧友电脑现在可以自动超频:不断加热直到事情融化;然后退了1位。
当然,如果某些百分比的线程超出了您通常允许的范围,或者如果某些其他软件启动并占用资源,您仍可能会遇到问题。
<强> tldr 强>;你必须在它将继续存在的机器上手动调整它。准备经常重调。