3 回答
TA贡献1853条经验 获得超18个赞
可以添加隐式垃圾回收,但是并没有成功。可能不仅是由于实施方面的复杂性,还因为人们没有足够快地达成普遍共识。
Bjarne Stroustrup自己的话:
我曾希望可以选择启用的垃圾收集器将成为C ++ 0x的一部分,但是我有足够的技术问题需要解决,只需详细说明这种收集器如何与语言的其余部分集成即可。 (如果提供)。与基本上所有C ++ 0x功能的情况一样,存在实验性实现。
有话题商量好了这里。
总体概述:
C ++功能非常强大,几乎可以做任何事情。因此,它不会自动将很多可能影响性能的事情推到您身上。垃圾回收可以通过智能指针轻松实现(智能对象包装带有引用计数的指针,当引用计数达到0时,这些对象会自动删除自身)。
C ++是在没有垃圾收集的情况下考虑竞争对手而构建的。与C和其他语言相比,效率是C ++必须抵制批评的主要问题。
垃圾收集有2种类型...
显式垃圾回收:
C ++ 0x将通过使用shared_ptr创建的指针进行垃圾回收
如果您想要它,则可以使用它;如果您不想要它,则不会被迫使用它。
如果您不想等待C ++ 0x,则当前还可以使用boost:shared_ptr。
隐式垃圾回收:
它没有透明的垃圾收集器。不过,它将成为未来C ++规范的重点。
为什么Tr1没有隐式垃圾回收?
C ++ 0x的tr1应该有很多东西,Bjarne Stroustrup在之前的采访中指出,tr1没有他想要的东西。
TA贡献1802条经验 获得超5个赞
在这里增加辩论。
垃圾回收存在一些已知问题,对它们的了解有助于理解C ++中为什么没有垃圾回收的问题。
1.性能
第一个抱怨通常是关于性能的,但是大多数人并没有真正意识到他们在说什么。如图所示,Martin Beckett问题可能不是性能本身,而是性能的可预测性。
当前有2个广泛使用的GC系列:
标记和扫描种类
参考计数种类
该Mark And Sweep快(对整体性能的影响较小),但它从一个“冻结世界”综合症患有:即当在GC踢,一切停止,直到GC作出了清理。如果您希望构建可以在几毫秒内响应的服务器...某些事务将无法达到您的期望:)
问题Reference Counting不同:引用计数会增加开销,尤其是在多线程环境中,因为您需要具有原子计数。此外,还有参考循环的问题,因此您需要一个聪明的算法来检测这些循环并消除它们(通常也通过“冻结世界”来实现,尽管频率较低)。总体而言,截至今天,这种方法(即使通常响应速度更快或更不频繁地冻结)也比慢Mark And Sweep。
我看过埃菲尔铁塔实施者的论文,他们试图实施一个Reference Counting垃圾收集器,该垃圾收集器的全球性能与Mark And Sweep没有“冻结世界”方面的相似。它需要用于GC的单独线程(典型)。该算法有点令人恐惧(最后),但是论文很好地完成了一次介绍一个概念并展示了算法从“简单”版本到成熟版本的演变。推荐阅读,只要我能把双手放回PDF文件上即可...
2.资源获取正在初始化(RAII)
这是一个常见的习惯用法C++,您将资源的所有权包装在一个对象中以确保正确释放它们。因为我们没有垃圾回收,所以它主要用于内存,但是它在许多其他情况下也很有用:
锁(多线程,文件句柄等)
连接(到数据库,另一台服务器...)
这个想法是适当地控制对象的生存期:
只要你需要它就应该还活着
完成后应将其杀死
GC的问题是,如果它对前者有所帮助并最终保证在以后……“最终”可能还不够。如果您释放锁,那么您真的希望它现在被释放,这样它就不会阻止任何进一步的呼叫!
使用GC的语言有两种解决方法:
当堆栈分配足够时不要使用GC:通常是为了解决性能问题,但是在我们的情况下,这确实有用,因为范围定义了生命周期
using构造...但是它是显式的(弱)RAII,而在C ++中,RAII是隐式的,因此用户不能不经意间犯错误(通过省略using关键字)
3.智能指针
智能指针通常表现为处理内存中的银弹C++。我经常听到:我们毕竟不需要GC,因为我们有智能的指针。
一个再错不过了。
智能指针确实有帮助:auto_ptr并且unique_ptr使用RAII概念,的确非常有用。它们是如此简单,您可以很容易地自己编写它们。
但是,当需要共享所有权时,这会变得更加困难:您可能会在多个线程之间共享,并且计数处理存在一些细微的问题。因此,自然会走向shared_ptr。
太好了,毕竟这就是Boost的目的,但这不是灵丹妙药。实际上,主要的问题shared_ptr是它模拟了由GC实施的GC,Reference Counting但是您需要自己全部实施循环检测... Urg
当然,这很weak_ptr麻烦,但是尽管如此,shared_ptr由于使用了这些周期,但不幸的是我已经看到内存泄漏了……而且当您处于多线程环境中时,这很难检测!
4.解决方案是什么?
没有灵丹妙药,但是和往常一样,这绝对是可行的。在没有GC的情况下,需要明确所有权:
如果可能的话,宁愿在给定的时间只有一个所有者
如果没有,请确保您的类图没有与所有权有关的任何周期,并通过巧妙地应用 weak_ptr
所以的确,拥有GC很棒。但是这不是小问题。同时,我们只需要卷起袖子。
- 3 回答
- 0 关注
- 423 浏览
添加回答
举报