Jon*_*s B 12 .net garbage-collection
好的,这是交易.有些人把他们的生命交给了.NET的垃圾收集器,有些人根本不相信它.
我是那些部分信任它的人之一,只要它不是非常重要的性能(我知道我知道......性能关键+ .net不是受欢迎的组合),在这种情况下我更喜欢手动处理我的对象和资源.
我要问的是,是否有关于垃圾收集器实际效率如何高效或低效的事实?
请不要分享任何个人意见或基于经验的可能假设,我想要无偏见的事实.我也不想进行任何亲/讨论,因为它不会回答这个问题.
谢谢
编辑:为了澄清,我基本上说:无论我们编写什么应用程序,资源是否关键,我们都可以忘记一切,让GC处理它或者不能处理它们?
我试图在实际中得到一个GC做什么和不做什么的答案以及如果有这样的情况,手动内存管理会成功的地方可能会失败.它有限制吗?我不知道如何进一步解释我的问题.
我对任何应用都没有任何问题,这是一个理论问题.
对大多数应用程序来说足够高效 但是你不必担心GC.在真正热门的系统,低延迟要求,你应该以一种完全避免它的方式编程.我建议你看看这份快速增加白皮书:
虽然GC执行速度非常快,但执行起来确实需要时间,因此在连续操作模式下进行垃圾收集会在延迟高度敏感的应用程序中引入不良延迟和延迟变化.例如,如果您每秒处理100,000条消息,并且每条消息使用一个小的临时2字符串,则为每条消息分配大约8个字节(这是字符串编码的函数和字符串对象的实现).因此,您每秒创建大约1MB的垃圾.对于可能需要在16小时内提供持续性能的系统,这意味着您必须清理16小时x 60分钟x 60秒x 1MB内存大约56 GB内存.您可以从垃圾收集器中获得的最佳结果是它将在第0代或第1代集合中完全清除它并导致抖动,最糟糕的是它将导致第2代垃圾收集以及相关的较大延迟峰值.
但是请注意,放弃诸如避免GC影响这样的技巧真的很难.您真的需要考虑您是否在需要考虑GC影响的性能要求中.
我可以告诉你一些我用.NET的垃圾收集器遇到的问题.
如果您正在运行使用服务器GC的应用程序(例如ASP.NET应用程序),那么您的延迟将非常糟糕,当您的任何线程都没有任何进展时,暂停时间大约为一秒.这是因为.NET 4服务器GC是一个停止世界的GC.显然,.NET 4.5将引入微软首个主要并发服务器GC.
我曾经写过一些检测代码,用于测量并发系统中使用内置集合的延迟,ConcurrentBag并且由于大量堆碎片而导致32位内存耗尽,因为.NET GC不会对大型对象进行碎片整理.我不得不将基于数组的数据结构替换为纯功能数据结构,这些数据结构分散在数百万个小块中,以避免在导致碎片的大对象堆(LOH)上出现任何问题.
我已经喜欢GC发现的缺陷这一引起GC,直到所有系统内存耗尽内存泄漏于是堆在一个巨大的GC周期清零指出,暂停,不仅所有的线程,但即使其他进程(因为系统已经交换了几分钟!
虽然最新的.NET GC中存在"低延迟"设置,但它实际上只是关闭了垃圾收集,因此您的程序会泄漏内存,直到您获得一次大量的GC暂停.微软似乎更喜欢这样的解决方法,如果你想要可用的延迟,就等于说"编写你自己的垃圾收集器".
但是,.NET GC通常非常好,并且在仔细使用时,可以从中获得良好的结果.例如,我最近编写了一个容错服务器,平均实现了114μs的门到门延迟,95%的延迟低于0.5ms.鉴于我在短短几个月内就用F#编写了整个平台,这与最先进的技术(见此处和此处)非常接近.与.NET GC相比,网络实际上对延迟的贡献更大.
| 归档时间: |
|
| 查看次数: |
1185 次 |
| 最近记录: |