ChatGPT解决这个技术问题 Extra ChatGPT

C ++中的垃圾收集库[关闭]

关闭。此问题不符合 Stack Overflow 准则。它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。 8年前关闭。改进这个问题

哪些免费和商业垃圾收集库可用于 C++,它们各自的优缺点是什么?

我感兴趣的是从该领域的实际使用中来之不易的经验教训,而不是营销或促销宣传。

无需详细说明与自动垃圾收集相关的通常权衡,但请务必提及使用的算法(引用计数、标记和清除、增量等)并简要总结后果。

重新打开的原因:在最初发布时,SO 上尚未禁止软件推荐。追溯应用规则是一种恶行,特别是因为还有可能将问题标记为历史问题,这就是我建议做的事情。所以我标记了重新打开的问题。
请参阅使用 BoehmGC 的 managedcpp.sourceforge.net,但对于专门使用 C++11 的 C++。

d
dubek

我过去曾成功使用过 Boehm collector。它是开源的,可用于商业软件。

它是一种保守的收集器,由垃圾收集技术领域最重要的研究人员之一开发的历史悠久。


一点说明:Boehm GC 不遵循指针和分配的内存区域。它甚至不知道内存地址是否是指针。因此 1) 使用 Boehm GC 仍然有可能无法再释放未使用的内存区域(如果它们被不是指针的数据“引用”)。 2) boehm GC 也会扫描非指针数据中的“指针”,如果你有几个指针但有很多数据(你有很多大数据块),这意味着很大的开销 3) Boehm GC 是纯 C 并且几乎不使用C 预处理器 4) 它不是线程安全的。
T
Tom Leys

Boost 的 smart pointers 范围很大,这意味着引用计数或范围内删除退出或侵入式引用计数。这些已经证明足以满足我们的需求。一个很大的优点是它都是免费的、开源的、模板化的 C++。因为它是引用计数,所以在大多数情况下,当一个对象被销毁时,它是高度确定的。


我使用 auto_ptr 取得了很大的成功。
盖克。 Auto_ptr 应该被拖到谷仓后面并射击。它有它的用途,但是孩子们:永远不要混合 auto_ptr 和集合。糟糕的juju结果。
@darthcoder - 同意,但是任何允许您混合 auto_ptr 和集合的 C++ 实现也应该拖到谷仓后面,等等。
@Tom Leys - 应该记住引用计数的智能指针不是GC的实现。它们不会自动处理循环引用,并且在实际应用程序中它们的性能更差(大量不必要的簿记,所有这些都在最重负载而不是空闲时间执行)。
我还质疑 shared_ptr 是有用的“确定性”的想法。本地对象实例上的析构函数确定性地运行 - 我们知道它在退出封闭块时执行。但在与 shared_ptr 相同的情况下,我们只知道引用计数已减少。 shared_ptr 的全部意义在于我们不知道其他地方是否仍然需要该对象,因此我们无法在本地确定它何时被销毁。如果您需要在退出某个范围时关闭“文件句柄”对象,请不要使用 shared_ptr
A
Amin

The Boehm garbage collector 是免费提供的,据说相当不错(我自己没有亲身经历)

关于 C++0x proposal for the Boehm garbage collector 的理论论文(PDF)

最初据说可以制作 C++0x , but will not make it after all(我想是由于时间限制)。

Proprosal N2670(对垃圾收集器的最低支持)确实在 2008 年 6 月获得批准,因此随着编译器实现对此进行了解,并且标准最终确定,C++ 的垃圾收集世界肯定会改变......


Afaik 提案 N2670 是插入 Boehm GC 的一个很好的尝试,它有详细的回退here
P
Paul Biggar

我经常使用 boehm-gc。它使用起来很简单,但是文档真的很差。有一个 C++ 页面,但很难找到。

基本上,您只需确保每个类都继承自它们的基类,并且始终将 gc_allocator 传递给容器。在许多情况下,您希望使用 libgccpp 来捕获 new 和 delete 的其他用途。这些主要是高级更改,我们发现我们可以在编译时使用#ifdef 关闭 GC,并且支持这一点只会影响一两个文件。

我的主要问题是你不能再使用 Valgrind,除非你先关闭收集器。虽然关闭收集器很容易做到,并且不需要重新编译,但如果您开始耗尽内存,显然无法使用它。


Afaik Boehm GC 可能在某些项目中很有用,但它有严重的后备问题,尤其是对于接近 Java 的任务。例如,它不是线程安全的,或者将数据视为指针。详细列表是 here
BoehmGC 的 C++ 部分非常不完整。有关如何使用 C++11 进行实际精确 GC 的示例,请参阅 managedcpp.sourceforge.net
l
larsivi

我知道的唯一一个是 Boehm,底部是一个传统的标记和扫描。它可能使用各种技术来优化这一点,但通常增量/分代/压缩 GC 将很难为 C++ 创建而不使用托管子集,例如您可以使用 .Net C++ 获得的内容。一些需要移动指针的方法可以通过编译器支持固定指针或读/写块来实现,但是对性能的影响可能太大,而且对 GC 的更改不一定是不重要的。


好吧,没有 GC 需要解释程序......也许你的意思是它需要编译器支持。
Afaik Boehm GC 可能在某些项目中很有用,但它有严重的后备问题,尤其是对于接近 Java 的任务。例如,它不是线程安全的,或者将数据视为指针。详细列表是 here
A
Arafangion

C++ 中 GC 的主要困难是需要处理 GC 意义上的不合作模块。即,处理从未考虑过 GC 编写的库。

这就是为什么经常建议使用 Boehm GC。


幸运的是,在编译 java 代码的情况下,使用非 gc 库的可能性要小得多。
R
Remi Lemarchand

您还可以使用 Microsoft 的托管 C++。 CLR 和 GC 非常可靠并用于服务器产品,但您必须使用 CLR 类型才能让 GC 实际收集 - 您不能只重新编译现有代码并删除所有删除语句。

我宁愿使用 C# 来编写全新的代码,但是托管 C++ 可以让您以更渐进的方式发展您的代码库。


缺点:1)它是微软特定的 2)它将代码编译到 CLR,即用于 VM。
C
Community

阅读 this 并仔细查看结论:

结论 问题的复杂解决方案,简单的解决方案被广泛使用,并将通过 C++0x 得到改进,使我们几乎不需要。对于要标准化的推荐语言功能,我们几乎没有经验。修复糟糕的软件复杂系统永远不会奏效。建议对语言进行较小的更改以改进未来的 GC 支持 - 以禁止隐藏指针(异或列表技巧)为例。最后 - 正面解决“C++ 不好,因为它没有 GC”参数。 C++ 不会产生垃圾,因此不需要 GC。显然,Java、C#、Objective C 等会产生大量垃圾。

是的,最后一句话是主观的,也是圣战的一部分。我使用 C++ 是因为我不喜欢有人需要为我倒垃圾的想法。市政厅就是这样做的,这对我来说就足够了。如果您需要 GC,请使用另一种语言。为正确的工作选择正确的工具。


你的结论完全是前后矛盾的。在 C++ 程序中,必须手动设计垃圾的收集方式。 (可能是你,也可能是下一个必须修复你的内存泄漏的可怜人)。在具有集成 GC 的语言中,没有人必须这样做。已经想通了。如果您想减少人们所做的无意义工作,请将您的工作基于 GC。
在需要 GC 的 c++ 中,您通常可以找到更合适且性能更高的解决方案。典型的用例是场景图。需要压缩场景图以消除内存中的漏洞。 Gc 可以做到这一点,但在 C++ 中,您不需要取出垃圾(额外且昂贵的任务)。您只需要使用快速清空的内存缓冲区。
不正确,C++ 生成垃圾是因为您的数据结构至少在临时图的复杂性上。对于 GC,您需要使用 ad hoc 解决方案,是的,日常经验是大型 C++ 二进制文件确实会泄漏,尽管开发人员的 ad hoc gc 付出了巨大的努力。 (好吧,java 进程也可能泄漏,但在 java 中,gc 所需的工作时间几乎总是在零左右)。
D
Dave Jarvis

这是我在寻找同样的东西时发现的商业产品

http://www.harnixtechnologies.ca/hnxgc/

过去,Geodesic Systems 还推出了一款名为 Great Circle 的产品,但看起来他们不再销售了。不知道是否将产品卖给了其他人。