简体   繁体   English

抑制C#垃圾回收

[英]Suppressing C# garbage collection

My application allocates a large amount of memory (millions of small objects totaling several gigabytes) and holds onto it for a long time. 我的应用程序分配了大量的内存(数百万个小对象,总计几千兆字节)并且长时间保留它。

  1. Is .NET wasting time checking through all of this data to do GC on it? 是.NET浪费时间检查所有这些数据来做GC吗?
  2. How often does the Gen 2 GC occur (the one that checks all objects)? Gen 2 GC多久出现一次(检查所有对象的那个)?
  3. Is there any way to reduce it's frequency or temporarily suppress it from occurring? 有没有办法降低它的频率或暂时抑制它的发生?
  4. I know exactly when I am ready for a large amount of memory to be collected, is there any way to optimize for that? 我确切地知道当我准备好收集大量内存时,有什么方法可以优化它吗? I am currently calling GC.Collect(); 我目前正在调用GC.Collect(); GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers(); at that time. 那时候。

Update: Perf counter "% Time in GC" is showing an average of 10.6%. 更新:Perf计数器“GC中的%时间”显示平均值为10.6%。

Unless you can confirm that the garbage collector is actively slowing the performance of your application, you should not take steps to cripple the functionality of your runtime environment. 除非您可以确认垃圾收集器正在积极地降低应用程序的性能,否则您不应采取措施来削弱运行时环境的功能。

Judging from your question, you have not confirmed that the GC is a problem. 从您的问题判断,您尚未确认GC是一个问题。 I severely doubt that it is. 我严重怀疑它是。

Optimize only what needs to be optimized. 仅优化需要优化的内容。

Look at the System.Runtime.GCSettings.LatencyMode property. 查看System.Runtime.GCSettings.LatencyMode属性。

Setting the GCServer property to true in the app.config will also help cut down on GC's (in my case 10 times less GC when enabled). 在app.config中将GCServer属性设置为true也有助于减少GC(在我的情况下,启用时减少10倍GC)。

You can stop the garbage collector from finalizing any of your objects using the static method: 您可以使用静态方法阻止垃圾收集器完成任何对象:

GC.SuppressFinalize(*your object*)

More information here: link text 更多信息: 链接文字

You can measure this using Performance Monitor. 您可以使用性能监视器进行测量。 Open perfmon and add the .NET CLR Memory related performance counters. 打开perfmon并添加与.NET CLR Memory相关的性能计数器。 These counters are process specific and with them you can track the number of collections and sizes of the various generations and more spefically for you the "% Time in GC". 这些计数器是特定于流程的,您可以使用它们跟踪各代的集合数量和大小,并且更加特别地为您指定“GC中的%时间”。 Here is the explain text for this counter: 以下是此计数器的说明文字:

% Time in GC is the percentage of elapsed time that was spent in performing a garbage collection (GC) since the last GC cycle. GC中的%时间是自上一个GC循环以来执行垃圾收集(GC)所花费的时间百分比。 This counter is usually an indicator of the work done by the Garbage Collector on behalf of the application to collect and compact memory. 此计数器通常表示垃圾收集器代表应用程序收集和压缩内存所做的工作。 This counter is updated only at the end of every GC and the counter value reflects the last observed value; 此计数器仅在每个GC结束时更新,计数器值反映最后观察到的值; its not an average. 它不是一般的。

If you watch these counters while running your program, you should have answer for the frequency and cost of the GC due to your memory decisions. 如果您在运行程序时观察这些计数器,则应该根据您的内存决策来回答GC的频率和成本。

Here is a good discussion of the various GC Performance Counters. 以下是各种GC性能计数器的良好讨论。 It seems that 10% is borderline okay. 似乎10%的边界没问题。

It will only (usually) happen when the GC needs some gen2 memory anyway (because gen1 is full). 它只会(通常)发生在GC需要一些gen2内存时(因为gen1已满)。 Are you asking this speculatively, or do you actually have a problem with GC taking a large proportion of your execution time? 你是在推测性地问这个问题,还是GC实际上有一个问题,因为你占用了大部分的执行时间? If you don't have a problem, I suggest you don't worry about it for the moment - but keep an eye on it with performance monitors. 如果您没有问题,我建议您暂时不要担心 - 但请注意性能监视器。

My ASP.NET application - B2B system - used to start at 35-40MB when the first user came to it. 我的ASP.NET应用程序 - B2B系统 - 当第一个用户访问它时,用于启动35-40MB。 After so minutes, the application used to grow up to 180 MB with 2 or 3 users hitting pages. 在这么几分钟之后,应用程序过去常常增长到180 MB,有2或3个用户点击页面。 After reading .net development best practices and GC performance guideline I find out that the problem was my application design. 在阅读.net开发最佳实践和GC性能指南后,我发现问题是我的应用程序设计。 I did not agree at once. 我立刻不同意。

I was horrified about how easy we can do mistakes. 我对于犯错是多么容易感到震惊。 I gave up many features and start to easy some objects up. 我放弃了许多功能,并开始轻松一些对象。 Meaning: 含义:

  1. Avoid mixing so much pages and intelligent and communicative user controls (the ones with lot of functionalities which actually most exist for each page that uses this control). 避免混合这么多页面以及智能和交流的用户控件(具有许多功能的控件,这些功能实际上对于使用此控件的每个页面最常存在)。

  2. Stop engendering universal functionalities on base classes. 停止在基类上产生通用功能。 Sometimes is preferable repeat. 有时候最好重复一次。 Inheritance is cost. 继承是成本。

  3. On some complex functionality I put everything on the same function. 在一些复杂的功能上,我将所有内容放在同一个函数上 YES, reaching 100 lines most. 是的,最多达到100行。 When I read this recommendation on .net performance guidance I did not believe it but it works. 当我在.net性能指导中阅读这篇建议时,我不相信它,但它有效。 Call stacks is a problem, use class properties over local variables is a problem. 调用堆栈是一个问题,使用类属性超过局部变量是一个问题。 Class level variables can be a hell… 班级变量可能是一个地狱......

  4. Stop using complex base classes, no base classes with more than 7 lines should exist. 停止使用复杂的基类,不应存在超过7行的基类。 If you spread bigger classes on the entire framework, you'll have problem. 如果你在整个框架上传播更大的类,你就会遇到问题。

  5. I start use more static objects and functionalities. 我开始使用更多的静态对象和功能。 I saw application wich other guy designed. 我看到其他人设计的应用程序。 All dataaccess objects methods (insert, update, delete, selects) was static ones. 所有dataaccess对象方法(插入,更新,删除,选择)都是静态的。 The application with more concurrent users never reaches out more than 45MB. 具有更多并发用户的应用程序永远不会超过45MB。

  6. To save some projects, I like stead state pattern. 为了节省一些项目,我喜欢改变状态模式。 I learned in the real world but the author Nygard also agree with me on his book: Release IT - Design and Deploy Production-Ready software. 我在现实世界中学到了,但作者Nygard也在他的书上同意我的观点:发布IT - 设计和部署生产就绪软件。 He calls such approach as steady state pattern. 他把这种方法称为稳态模式。 This patterns says we may need something to free up idle resources. 这种模式表明我们可能需要一些东西来释放闲置资源。

  7. You may want play with on machine config file. 您可能想要在机器配置文件上玩。 On the attribute memoryLimit you'll indicate the percentage of memory which could be reached before a process recycles. 在属性memoryLimit上,您将指示在进程回收之前可以达到的内存百分比。

  8. You may also want play with on machine config file. 您可能还希望使用机器配置文件。 On this attribute, GC will dictate the machine behaviour (Workstation GC and Server GC). 在此属性上,GC将指示机器行为(Workstation GC和Server GC)。 This option may dramatically changes memory consumption behaviour too. 此选项也可能会显着改变内存消耗行为。

I had lot of success when I started to care about this items. 当我开始关心这些物品时,我取得了很大的成功。 Hope this help. 希望这有帮助。

-- EDITED IN 04-05-2014 I've changed my mind about many things due to GC new versions improvements and the advances of HTML 5 and MVC framework. - 编辑于04-05-2014由于GC新版本的改进以及HTML 5和MVC框架的进步,我已经改变了很多想法。

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

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