我们有一个运行在64位Windows服务器上的64位C#/。Net3.0应用程序。应用程序可能会不时使用大量可用内存。在某些情况下,应用程序停止分配额外的内存并显着减慢速度(慢500倍)。当我从任务管理器检查内存时,使用的内存量几乎没有变化。应用程序继续运行非常缓慢,并且永远不会出现内存不足异常。 有任何想法吗?如果需要更多数据,请与我们联系。
答案 0 :(得分:5)
当您达到物理内存限制时,操作系统将开始分页(即将内存写入磁盘)。这确实会导致你看到的那种放缓。
解决方案?
如果内存不是问题,那么您的应用程序是否可能非常难以使用CPU?你看到CPU接近100%?如果是这样,请检查反复迭代的大型集合。
答案 1 :(得分:5)
您可以尝试enabling server mode for the Garbage Collector。默认情况下,所有.NET应用程序都在工作站模式下运行,GC会在保持应用程序运行的同时尝试进行扫描。如果打开服务器模式,它会暂时停止应用程序,以便它可以更快地释放内存,并且它还为每个处理器/核心使用不同的堆。
大多数服务器应用程序都会看到使用GC服务器模式的性能提升,特别是如果它们分配了大量内存。缺点是你的应用程序将在内存开始耗尽时基本停止(直到GC完成)。
* 要启用此模式,请将以下内容插入app.config
或web.config
:
<configuration>
<runtime>
<gcServer enabled="true"/>
</runtime>
</configuration>
答案 2 :(得分:2)
Investigating Memory Issues(MSDN文章)
答案 3 :(得分:2)
其他答案中提到了很多好东西。但是,无论如何,我将以两便士(或美分 - 取决于你来自哪里!)筹码。
假设这确实是一个64位的过程,正如你所说,这里有一些调查途径......
您正在检查哪种内存使用情况?内存使用情况还是VMem大小? VMem大小实际上很重要,因为它适用于分页和非分页内存。如果两个数字远远不够,那么内存使用量确实是减速的原因。
当事情开始变慢时,整个服务器的实际内存使用量是多少?减速是否也适用于其他应用程序?如果是这样,那么您可能会遇到内核内存问题 - 这可能是由于大量磁盘访问和低级资源使用(例如,创建20000互斥锁,或通过使用Win32 HBitmaps的代码加载几千位图)。您可以在任务管理器上获得这方面的一些指示(虽然Windows 2003的版本比2008年更直接提供信息)。
当你说应用程序速度明显变慢时,你怎么知道?你在使用庞大的词典或列表吗?是不是内部数据结构变得如此之大,以至于使内部算法执行的工作复杂化?当你得到大量数据时,一些算法可能会开始变慢几个数量级。
应用程序在全速运行时的CPU负载是多少?实际上与减速发生时相同吗?如果CPU使用率随着内存使用量的增加而降低,那么这就意味着无论它正在做什么都会让操作系统更长时间地完成,这意味着它可能会给操作系统带来太多负担。如果CPU负载没有差异,那么我的猜测是它的内部数据结构变得如此之大以至于减慢了你的算法。
我当然会考虑在应用程序上运行Perfmon - 从一些.Net和本机内存计数器,Cache命中和未命中以及磁盘队列长度开始。在应用程序的过程中从启动到运行它像哮喘龟一样运行它,你也可能从中得到一个线索。
答案 4 :(得分:1)
撇开其他答案后,我会说有很多好主意。这是我没看到的一个:
获取内存分析器,例如SciTech的MemProfiler。它会告诉你什么是分配,什么,它会告诉你整个切片。
它还有视频教程,以防您不知道如何使用它。在我的情况下,我发现我有IDisposable实例,我没有使用(...)