简体   繁体   English

达到内存限制会降低.Net应用程序的速度

[英]Hitting a memory limit slows down the .Net application

We have a 64bit C#/.Net3.0 application that runs on a 64bit Windows server. 我们有一个64位C#/。Net3.0应用程序,运行在64位Windows服务器上。 From time to time the app can use large amount of memory which is available. 应用程序可能会不时使用大量可用内存。 In some instances the application stops allocating additional memory and slows down significantly (500+ times slower).When I check the memory from the task manager the amount of the memory used barely changes. 在某些情况下,应用程序停止分配额外的内存并显着减慢速度(慢500倍)。当我从任务管理器检查内存时,使用的内存量几乎没有变化。 The application keeps on running very slowly and never gives an out of memory exception. 应用程序继续运行非常缓慢,并且永远不会出现内存不足异常。 Any ideas? 有任何想法吗? Let me know if more data is needed. 如果需要更多数据,请与我们联系。

The moment you are hitting the physical memory limit, the OS will start paging (that is, write memory to disk). 当您达到物理内存限制时,操作系统将开始分页(即将内存写入磁盘)。 This will indeed cause the kind of slowdown you are seeing. 这确实会导致你所看到的那种放缓。

Solutions? 解决方案?

  • Add more memory - this will only help until you hit the new memory limit 添加更多内存 - 这只会在您达到新的内存限制之前有所帮助
  • Rewrite your app to use less memory 重写您的应用程序以减少内存使用
  • Figure out if you have a memory leak and fix it 弄清楚你是否有内存泄漏并修复它

If memory is not the issue, perhaps your application is hitting CPU very hard? 如果内存不是问题,也许你的应用程序非常难以点击CPU? Do you see the CPU hitting close to 100%? 你看到CPU接近100%? If so, check for large collections that are being iterated over and over. 如果是这样,请检查一遍又一遍地迭代的大型集合。

You might try enabling server mode for the Garbage Collector . 您可以尝试为垃圾收集器启用服务器模式 By default, all .NET apps run in Workstation Mode, where the GC tries to do its sweeps while keeping the application running. 默认情况下,所有.NET应用程序都在工作站模式下运行,GC会在保持应用程序运行的同时尝试进行扫描。 If you turn on server mode, it temporarily stops the application so that it can free up memory (much) faster, and it also uses different heaps for each processor/core. 如果打开服务器模式,它会暂时停止应用程序,以便它可以更快地释放内存,并且它还为每个处理器/核心使用不同的堆。

Most server apps will see a performance improvement using the GC server mode, especially if they allocate a lot of memory. 大多数服务器应用程序将使用GC服务器模式看到性能提升,特别是如果它们分配了大量内存。 The downside is that your app will basically stall when it starts to run out of memory (until the GC is finished). 缺点是,当应用程序开始耗尽内存时,您的应用程序将基本停止(直到GC完成)。

* To enable this mode, insert the following into your app.config or web.config : *要启用此模式,请将以下内容插入app.configweb.config

<configuration>
   <runtime>
      <gcServer enabled="true"/>
   </runtime>
</configuration>

There is an awful lot of good stuff mentioned in the other answers. 其他答案中提到了很多好东西。 However, I'm going to chip in my two pence (or cents - depending on where you're from!) anyway. 但是,无论如何,我要用两便士(或美分 - 取决于你来自哪里!)来筹码。

Assuming that this is indeed a 64-bit process as you have stated, here's a few avenues of investigation... 假设这确实是你所说的64位进程,这里有一些调查途径......

Which memory usage are you checking? 您正在检查哪种内存使用情况? Mem Usage or VMem Size? 内存使用情况还是VMem大小? VMem size is the one that actually matters, since that applies to both paged and non-paged memory. VMem大小实际上很重要,因为它适用于分页和非分页内存。 If the two numbers are far out of whack, then the memory usage is indeed the cause of the slow-down. 如果这两个数字远远不够,那么内存使用确实是减速的原因。

What's the actual memory usage across the whole server when things start to slow down? 当事情开始变慢时,整个服务器的实际内存使用量是多少? Does the slow down also apply to other apps? 减速是否也适用于其他应用程序? If so, then you may have a kernel memory issue - which can be due to huge amounts of disk accessing and low-level resource usage (for example, create 20000 mutexes, or load a few thousand bitmaps via code that uses Win32 HBitmaps). 如果是这样,那么您可能会遇到内核内存问题 - 这可能是由于大量磁盘访问和低级资源使用(例如,创建20000互斥锁,或通过使用Win32 HBitmaps的代码加载几千位图)。 You can get some indication of this on the Task Manager (although Windows 2003's version is more informative directly on this than 2008's). 您可以在任务管理器上获得一些指示(虽然Windows 2003的版本比2008年更直接提供信息)。

When you say that the app gets significantly slower, how do you know? 当你说应用程序速度明显变慢时,你怎么知道? Are you using vast dictionaries or lists? 你在使用庞大的词典或列表吗? Could it not just be that the internal data structures are getting so big so as to complicate the work any internal algorithms are performing? 是不是内部数据结构变得如此之大,以至于使内部算法执行的工作复杂化? When you get to huge numbers some algorithms can start to become slower by orders of magnitude. 当你得到大量数据时,一些算法可能会开始变慢几个数量级。

What's the CPU load of the application when it's running at full-pelt? 当应用程序以全毛皮运行时,应用程序的CPU负载是多少? Is actually the same as when the slow-down occurs? 实际上与减速发生时相同吗? If the CPU usage decreases as the memory usage goes up, then that means that whatever it's doing is taking the OS longer to fulfill, meaning that it's probably putting too much load on the OS. 如果CPU使用率随着内存使用量的增加而降低,那么这就意味着无论它正在做什么都会让操作系统更长时间地完成,这意味着它可能会给操作系统带来太多负担。 If there's no difference in CPU load, then my guess is it's internal data structures getting so big as to slow down your algos. 如果CPU负载没有差异,那么我的猜测是它的内部数据结构变得如此之大以至于减慢你的算法。

I would certainly be looking at running a Perfmon on the application - starting off with some .Net and native memory counters, Cache hits and misses, and Disk Queue length. 我肯定会考虑在应用程序上运行Perfmon - 从一些.Net和本机内存计数器,Cache命中和未命中以及磁盘队列长度开始。 Run it over the course of the application from startup to when it starts to run like an asthmatic tortoise, and you might just get a clue from that as well. 在应用程序的过程中从启动到运行它像哮喘龟一样运行它,你也可能从中得到一个线索。

Having skimmed through the other answers, I'd say there's a lot of good ideas. 撇开其他答案,我会说有很多好主意。 Here's one I didn't see: 这是我没看到的一个:

Get a memory profiler, such as SciTech's MemProfiler. 获取内存分析器,例如SciTech的MemProfiler。 It will tell you what's being allocated, by what, and it will show you the whole slice n dice. 它将告诉你什么是分配,什么,它将显示整个切片骰子。

It also has video tutorials in case you don't know how to use it. 它还有视频教程,以防您不知道如何使用它。 In my case, I discovered I had IDisposable instances that I wasn't Using(...) 在我的情况下,我发现我有IDisposable实例,我没有使用(...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM