首页 / 知识
关于C#:如何避免在实时.NET应用程序中进行垃圾回收?
2023-04-16 17:04:00

How to avoid garbage collection in real time .NET application?我正在编写一个金融C#应用程序,该应用程序从网络接收消息,根据消息类型将它们转换为不同的对象,最后将应用程序业务逻辑应用于它们。 重点是在应用了业务逻辑之后,我确定我将不再需要该实例。我不想等待垃圾回收器释放它们,而是要显式"删除"它们。 在C#中是否有更好的方法,应该使用对象池来重用总是相同的一组实例,还是有更好的策略? 目标是避免垃圾收集在时间紧迫的过程中使用任何CPU。 请勿立即删除它们。为每个对象调用垃圾回收器是一个坏主意。通常,您真的根本不想弄乱垃圾收集器,即使时间紧迫的进程也是如此,如果它们如此敏感,它们就只是竞相等待的条件。 但是,如果您知道自己的应用在繁忙时段与轻负载时段之间,则可以在达到轻负载时段时尝试使用更通用的GC.Collect(),以鼓励在下一个繁忙时段之前进行清理。 查看此处:http://msdn.microsoft.com/zh-cn/library/bb384202.aspx 您可以告诉垃圾收集器您目前正在做一些重要的事情,它将对您有好处。 您打自己-使用对象池并重复使用这些对象。调用这些对象的语义将需要隐藏在工厂外观的后面。您需要以某种预定义的方式扩展池。每次达到极限时,大小可能都会增加一倍-高水位算法或固定百分比。我强烈建议您不要调用GC.Collect()。 当池中的负载足够低时,您可以收缩池,最终将触发垃圾回收-让CLR担心它。 尝试猜测垃圾收集器通常是一个非常糟糕的主意。在Windows上,垃圾收集器是一个世代的垃圾收集器,可以依靠它来提高效率。此一般规则有一些值得注意的例外-最常见的是一次发生的事件,您知道一个事实会导致许多旧对象死亡-一旦将对象提升到Gen2(寿命最长)他们倾向于闲逛。 在您提到的情况下,听起来好像您正在生成许多短期对象-这些将导致Gen0集合。无论如何,这些情况相对经常发生,并且是最有效的。如果愿意,可以通过具有可重用的对象池来避免它们,但是最好在执行此类操作之前确定GC是否存在性能问题-CLR分析器是执行此操作的工具。 请注意,不同的.NET框架中的垃圾收集器有所不同-在紧凑型框架(可在Xbox 360和移动平台上运行)上,它是非世代的GC,因此您必须拥有更多的能力注意程序会产生什么垃圾。 强制使用GC.Collect()通常是一个坏主意,让GC发挥其最大作用。听起来最好的解决方案是使用一个可以在必要时增长的对象池-我已经成功使用了这种模式。 这样,您不仅可以避免垃圾收集,而且还可以避免常规分配成本。 最后,您确定GC引起了您的问题吗?在实施任何节省性能的解决方案之前,您可能应该测量并证明这一点-您可能会导致自己不必要的工作! "目标是避免垃圾收集在时间紧迫的过程中使用任何CPU " 问:如果时间紧迫,意味着您正在听一些深奥的硬件,您不能错过这个中断吗? A:如果是这样,则C#不是要使用的语言,则需要使用汇编语言,C或C。 问:如果在关键时刻,您是指管道中有很多消息,而您又不想让垃圾收集器放慢速度吗? A:如果是这样,您就不必担心了。从对象的声音来看,它们的寿命很短,这意味着垃圾回收器将非常有效地回收它们,而不会出现明显的性能延迟。 但是,唯一可以确定的方法就是对其进行测试,将其设置为运行一整夜以处理恒定的测试消息流,如果您的性能统计信息可以在GC启动时发现(并且即使您可以发现它,但如果它真的很重要,我会感到更加惊讶)。 应用程序强度有多大?我编写了一个应用程序,该应用程序以8KB的块捕获3个声卡(Managed DirectX,44.1KHz,立体声,16位),然后将3个流中的2个通过TCP / IP发送到另一台计算机。 UI会为3个通道的每个通道渲染一个音频电平表和(平滑的)滚动标题/艺术家。它可以在XP,1.8GHz,512MB等PC上运行。该应用使用大约5%的CPU。 我没有手动调用GC方法。但是我确实不得不调整一些浪费的东西。我使用RedGate的Ant探查器来细化那些浪费的部分。一个很棒的工具! 我想使用一个预先分配的字节数组池,但是托管DX程序集在内部分配字节缓冲区,然后将其返回给App。原来,我不必这样做。 对垃圾收集器的行为有一个很好的了解和感受,您将了解为什么不建议您在这里考虑什么。除非您真的很喜欢CLR花很多时间在内存中重新排列对象。
从它的声音看来,您似乎在谈论确定性终结(C中的析构函数),而C#中不存在。在C#中,最接近的东西是Disposable模式。基本上,您实现IDisposable接口。 基本模式是这样的:
如果绝对时间紧迫,那么您应该使用C / C之类的确定性平台。即使调用GC.Collect()也会生成CPU周期。 您的问题开始于关于要节省内存但要摆脱对象的建议。这是空间关键的优化。您需要决定自己真正想要的是什么,因为GC在优化这种情况方面比人为更好。 为什么每次收到消息时都不会创建对象的新实例,而是为什么不重用已经使用的对象?这样,您就不会与垃圾收集器进行对抗,堆内存也不会碎片化。** 对于每种消息类型,您可以创建一个池来保存未使用的实例。每当收到网络消息时,您都会查看消息类型,从适当的池中拉出一个等待的实例,然后应用您的业务逻辑。之后,将消息对象的实例放回其池中。 您很可能希望通过实例"延迟加载"池,以便轻松扩展代码。因此,您的池类将需要检测何时已拉空实例,并在派发空实例之前将其填满。然后,当调用代码将其放回池中时,它是一个真实实例。 ** "对象池是一种使用模式,它允许对象被重用而不是分配和释放,这有助于防止堆碎片和昂贵的GC压缩。"" http://geekswithblogs.net/robp/archive/2008/08/07/speedy-c-part-2-optimizing-memory-allocations---pooling-and.aspx 池中每种类型的实例数量可能有限,然后重复使用已经完成的实例。池的大小取决于您将处理的消息量。 理论上,如果您的CPU负载过重或除非确实需要,GC不应运行。但是如果有必要,您可能只想将所有对象都保存在内存中(也许是单例实例),并且除非准备好就不要清理它们。这可能是保证GC运行的唯一方法。 |
最新内容
相关内容
linux实时读日志命令?
linux实时读日志命令?,系统,信息,实时,工作,对比,管理,时间,命令,日志,平均,Linux服务器查看日志的几种方法1、如下图所示,先cd到我们需要监控linux实时读日志命令?
linux实时读日志命令?,系统,信息,实时,工作,对比,管理,时间,命令,日志,平均,Linux服务器查看日志的几种方法1、如下图所示,先cd到我们需要监控linux命令实时显示?
linux命令实时显示?,系统,实时,时间,信息,情况,命令,对比,电脑,名称,一致,linux用set命令显示当前模式set命令作主要是显系统中已经存在的shel查看linux类型命令?
查看linux类型命令?,系统,信息,命令,状态,数据,数字,情况,地址,类型,文件,linux查看系统命令是什么1、linux怎么查看系统版本呢,下面就让我们来linux删除类型命令?
linux删除类型命令?,系统,档案,命令,文件,名称,环境,数据,不了,目录,文件夹,关于linux的删除命令命令格式:rm [选项] 文件… 命令功能:删除一个linux中实时更新命令?
linux中实时更新命令?,系统,数据,实时,管理,服务,命令,名字,工作,信息,软件,linux命令求解,如何更新以及还原?1、使用 yum check-update 命令查看linux库类型命令?
查看linux库类型命令?,系统,工作,信息,状态,电脑,命令,工具,代码,地址,发行,如何查看Linux上程序或进程用到的库查看程序依赖的动态库:readelflinux网卡类型命令?
linux网卡类型命令?,网络,系统,地址,信息,设备,状态,服务,名称,名字,网卡,如何配置Linux网卡配置网卡地址:点击 网络(K) 按钮进行配置网络 选择linux实时抓取命令?
linux实时抓取命令?,网络,状态,信息,系统,服务,实时,命令,名称,情况,暂停,怎么查看linux正在运行的命令ps aux:ps 命令用于报告当前系统的进程linux查看命令类型用?
linux查看命令类型用?,信息,系统,情况,命令,实时,工作,设备,电脑,文件,类型,如何区分linux文件类型?1、普通文件类型 Linux中最多的一种文件类linux命令三种类型?
linux命令三种类型?,工作,地址,系统,标准,时间,管理,命令,目录,信息,文件,linux常用命令linux常用命令:查看内核版本:uname-a。图形界面:init5或linux命令和应用程序?
linux命令和应用程序?,软件,系统,环境,管理,基础,情况,位置,电脑,工具,中心,在linux下如何装应用程序?需要什么命令啊首先从官网下载hdf5,根据