我的应用程序分配了大量内存(数百万个小对象,总计几千兆字节)并且长时间保留它。
更新: Perf计数器“GC中的%时间”平均显示为10.6%。
答案 0 :(得分:24)
除非您确认垃圾收集器正在积极降低应用程序的性能,否则您不应采取措施来削弱运行时环境的功能。
从您的问题判断,您尚未确认GC是个问题。我严重怀疑它是不是。
仅优化需要优化的内容。
答案 1 :(得分:9)
查看System.Runtime.GCSettings.LatencyMode
属性。
在app.config中将GCServer属性设置为true也有助于减少GC(在我的情况下,启用时减少10倍的GC)。
答案 2 :(得分:9)
答案 3 :(得分:7)
您可以使用性能监视器进行测量。打开perfmon并添加与.NET CLR Memory相关的性能计数器。这些计数器是特定于流程的,您可以使用它们跟踪各代的集合数量和大小,并且更加特别地为您指定“GC中的%时间”。以下是此计数器的说明文字:
%GC中的时间是百分比 花费的经过时间 执行垃圾收集(GC) 自上一次GC循环以来。这个柜台 通常是工作的一个指标 由垃圾收集器完成 代表申请收集 和紧凑的记忆。这个柜台是 仅在每个GC结束时更新 并且计数器值反映了 最后观察到的值;它不是 平均。
如果您在运行程序时观察这些计数器,则应该根据您的内存决定来回答GC的频率和成本。
Here是对各种GC性能计数器的良好讨论。似乎10%的边界是正常的。
答案 4 :(得分:3)
只有当GC需要一些gen2内存时才会(通常)发生(因为gen1已满)。你是在推测性地问这个问题,还是GC实际上有一个问题,因为你占用了大部分的执行时间?如果您没有问题,我建议您暂时不要担心 - 但请注意性能监视器。
答案 5 :(得分:1)
我的ASP.NET应用程序 - B2B系统 - 当第一个用户访问它时,用于启动35-40MB。在这么几分钟之后,应用程序过去常常增长到180 MB,有2或3个用户点击页面。 在阅读.net开发最佳实践和GC性能指南后,我发现问题是我的应用程序设计。我不同意。
我很害怕我们犯错误有多容易。我放弃了许多功能,并开始轻松一些对象。含义:
避免混合这么多页面以及智能和交流的用户控件(具有许多功能的控件,这些功能实际上对于使用此控件的每个页面最为存在)。
停止在基类上产生通用功能。有时候最好重复一次。继承是成本。
在一些复杂的功能上,我把所有东西放在同一个函数上。是的,最多达到100行。 当我在.net性能指导中阅读这篇建议时,我不相信它,但它有效。调用堆栈是一个问题,使用类属性超过局部变量是一个问题。班级变量可能是一个地狱......
停止使用复杂的基类,不应存在超过7行的基类。如果你在整个框架上传播更大的类,你就会遇到问题。
我开始使用更多静态对象和功能。我看到其他人设计的应用程序。所有dataaccess对象方法(插入,更新,删除,选择)都是静态的。具有更多并发用户的应用程序永远不会超过45MB。
为了保存一些项目,我喜欢改变状态模式。我在现实世界中学到了,但作者Nygard也在他的书上同意我的观点:发布IT - 设计和部署生产就绪软件。他把这种方法称为稳态模式。这种模式表明我们可能需要一些东西来释放闲置的资源。
您可能需要使用机器配置文件。在属性memoryLimit上,您将指示在进程回收之前可以达到的内存百分比。
您可能还想玩机器配置文件。在此属性上,GC将指示机器行为(Workstation GC和Server GC)。此选项也可能会显着改变内存消耗行为。
当我开始关心这些物品时,我取得了很大的成功。希望这有帮助。
- 2014年5月4日编辑 由于GC新版本的改进以及HTML 5和MVC框架的进步,我已经改变了很多想法。