【发布时间】:2012-01-30 23:52:52
【问题描述】:
情况
我创造了一个怪物。 Applikentstein 是一个 RAM 杀手,我仍然无法非常清楚地理解它是如何以及为什么在设计上如此流氓。基本上,它是一个计算应用程序,可以为 N 个场景启动测试组合。每个测试都在一个专用线程中进行,包括读取大型二进制数据、处理它并将结果放入数据库。
数据在读取时首先被放入缓冲队列(~100MB),并在处理时从流中出列。在处理过程中,数据块被跟踪到数组中。在线程方面,我有一个包含 N 个工作人员的工作人员缓冲区队列,每次一个工作人员完成并死亡时,都会通过队列启动一个新工作人员。
如果我启动太多线程(“太多”取决于系统 RAM)会发生以下情况
问题是 RAM 使用斜率在某些时候并没有变平,它只是不断增长,然后不时下降(几个线程完成,GC 做家务),但是一旦启动新线程,它就会反弹随着时间的推移,回来,越来越高(可能在这里泄漏)
随着时间的推移,我问过this 一个问题,that 一个和this 另一个。 现在是我感觉的时候了,我了解的越多,我真正了解的就越少。 (叹气)
问题
现在,我想对 究竟 是如何在 .Net 下管理内存有一个清晰的解释/资源。
我知道有很多关于这个广泛主题的文学/博客文章。但是这个话题太大了,我真的不知道从哪里开始而不失去自己(以及我公司的宝贵时间)。我想保持专注和目标导向。
第二,当我试图在实验室条件下模拟/再现上面的陡坡(由 RAM'saurus Monster “自然”创建)时,“倾斜”出现了,以隔离这种行为并找到解决方法(即监控进程使用的内存并将其限制为总内存的 X%,方法是停止任何新线程的创建)。
为什么在实验室条件下(使用一些消耗内存的多线程循环)如此难以重现我的流氓程序似乎很容易做的事情(在任务管理器中将 RAM 放在膝盖上)? GC 似乎会定期清理原型中的内容,而我的应用程序似乎将很多引用的内容保留在 RAM 中。怎么会 ?
第三个令人费解的事情是缓存的工作方式:为什么 firefox 使用高达 1 Gb 的内存并使用缓存,而我的应用程序只是破坏了 RAM?是否有可能正在运行的线程大量/频繁地使用数据,因此它永远不会被缓存?
跟踪和线索
我已经使用了 VS 分析器并确定了一些瓶颈(大数组排序),使用了 GCRoot 和 WinDBG 控制台。每次我狙击更多漏洞并修复其中一些(或多或少,比如缺少事件取消订阅等等......)
我知道我对记忆的一些基本概念的理解仍然很差,这是事实。这就是为什么我在这里要求领导。我准备阅读明智的资源并了解更多信息,并遵循一些开明的建议。
【问题讨论】:
-
你创建了多少线程?每个线程使用 1MB 堆栈空间。也在看大型对象堆计数器吗?也许您那里有泄漏和/或碎片。
-
@ChrisO 这取决于可用的 RAM。 N 通常在 10 到 50 之间
-
您正在使用大量 RAM,因为您拥有的内存太多了。你有 5 GB 根本没有被使用,非常浪费:)
-
@HansPassant。嗨汉斯! (你是由 SOF 付钱来困扰论坛的吗 :-P) 是的,这实际上是一个 HPC。我正在对其进行大量计算,而 RAM 饱和的事实阻止了我尽可能高效地使用它。在这张快照之后的 30 00 万,RAM 已经满了,以至于挂掉了。
-
下次等30分钟再做截图:P
标签: c# performance