抑制 C# 垃圾收集

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/975947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:40:55  来源:igfitidea点击:

Suppressing C# garbage collection

c#garbage-collection

提问by Fantius

My application allocates a large amount of memory (millions of small objects totaling several gigabytes) and holds onto it for a long time.

我的应用程序分配了大量内存(数百万个小对象,总计数 GB)并保留了很长时间。

  1. Is .NET wasting time checking through all of this data to do GC on it?
  2. How often does the Gen 2 GC occur (the one that checks all objects)?
  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.WaitForPendingFinalizers(); at that time.
  1. .NET 是否在浪费时间检查所有这些数据以对其进行 GC?
  2. Gen 2 GC(检查所有对象的那个)多久发生一次?
  3. 有没有办法减少它的频率或暂时抑制它的发生?
  4. 我确切地知道什么时候我准备好收集大量内存,有什么方法可以优化吗?我目前正在调用 GC.Collect(); GC.WaitForPendingFinalizers(); 那时候。

Update: Perf counter "% Time in GC" is showing an average of 10.6%.

更新:Perf 计数器“% Time in GC”显示平均为 10.6%。

采纳答案by Welbog

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. I severely doubt that it is.

从你的问题来看,你还没有确认GC有问题。我严重怀疑它是。

Optimize only what needs to be optimized.

只优化需要优化的部分。

回答by Jon Skeet

It will only (usually) happen when the GC needs some gen2 memory anyway (because gen1 is full). Are you asking this speculatively, or do you actually have a problem with GC taking a large proportion of your execution time? 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.

它只会(通常)在 GC 需要一些 gen2 内存时发生(因为 gen1 已满)。您是推测性地问这个问题,还是您实际上对 GC 占用了大部分执行时间有问题?如果您没有问题,我建议您暂时不要担心 - 但请使用性能监视器密切关注。

回答by leppie

Look at the System.Runtime.GCSettings.LatencyModeproperty.

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(在我的情况下,启用时 GC 减少 10 倍)。

回答by Ken Pespisa

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

更多信息在这里: 链接文本

回答by Hyman Bolding

You can measure this using Performance Monitor. Open perfmon and add the .NET CLR Memory related performance counters. 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". Here is the explain text for this counter:

您可以使用性能监视器来衡量这一点。打开 perfmon 并添加与 .NET CLR 内存相关的性能计数器。这些计数器是特定于进程的,您可以使用它们跟踪不同代的集合数量和大小,更具体地说是“GC 时间百分比”。这是此计数器的解释文本:

% Time in GC is the percentage of elapsed time that was spent in performing a garbage collection (GC) since the last GC cycle. 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; its not an average.

% Time in GC 是自上次 GC 周期以来执行垃圾收集 (GC) 所花费的时间百分比。这个计数器通常是垃圾收集器代表应用程序收集和压缩内存所做工作的指标。该计数器仅在每次 GC 结束时更新,并且计数器值反映上次观察到的值;它不是一个平均值。

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 频率和成本。

Hereis a good discussion of the various GC Performance Counters. It seems that 10% is borderline okay.

是对各种 GC 性能计数器的很好的讨论。似乎 10% 是临界值。

回答by Eduardo Xavier

My ASP.NET application - B2B system - used to start at 35-40MB when the first user came to it. After so minutes, the application used to grow up to 180 MB with 2 or 3 users hitting pages. After reading .net development best practices and GC performance guideline I find out that the problem was my application design. I did not agree at once.

我的 ASP.NET 应用程序 - B2B 系统 - 当第一个用户使用它时,它的启动大小为 35-40MB。几分钟后,应用程序曾经增长到 180 MB,有 2 或 3 个用户点击页面。在阅读了 .net 开发最佳实践和 GC 性能指南后,我发现问题出在我的应用程序设计上。我没有立刻同意。

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. When I read this recommendation on .net performance guidance I did not believe it but it works. 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. 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. The application with more concurrent users never reaches out more than 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. 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.

  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). This option may dramatically changes memory consumption behaviour too.

  1. 避免混合如此多的页面和智能且可交流的用户控件(这些控件具有许多功能,实际上对于使用此控件的每个页面都存在)。

  2. 停止在基类上生成通用功能。有时最好重复。继承是有代价的。

  3. 在一些复杂的功能上,我把所有东西都放在同一个功能上。是的,最多达到 100 行。当我在 .net 性能指南上阅读此建议时,我不相信它,但它确实有效。调用堆栈是一个问题,使用类属性而不是局部变量是一个问题。类级别的变量可能是地狱......

  4. 停止使用复杂的基类,不应存在超过 7 行的基类。如果你在整个框架上传播更大的类,你会遇到问题。

  5. 我开始使用更多的静态对象和功能。我看到了其他人设计的应用程序。所有数据访问对象方法(插入、更新、删除、选择)都是静态的。具有更多并发用户的应用程序永远不会超过 45MB。

  6. 为了保存一些项目,我喜欢稳态模式。我在现实世界中学习,但作者 Nygard 在他的书上也同意我的观点:发布 IT - 设计和部署生产就绪软件。他称这种方法为稳态模式。这种模式表明我们可能需要一些东西来释放空闲资源。

  7. 您可能想在机器配置文件上玩。在属性 memoryLimit 上,您将指示在进程回收之前可以达到的内存百分比。

  8. 您可能还想使用机器配置文件。在此属性上,GC 将决定机器行为(工作站 GC 和服务器 GC)。此选项也可能会显着改变内存消耗行为。

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.

-- 于 2014 年 4 月 5 日编辑,由于 GC 新版本的改进以及 HTML 5 和 MVC 框架的进步,我改变了对很多事情的看法。