垃圾收集的想法

时间:2011-04-19 09:14:29

标签: c++ c garbage-collection language-design microcontroller

我正在研究一种使用C ++作为中间语言的玩具语言,目前它只支持三种类型,包括基类,整数,列表和lambda。所有函数都来回传递基类。编译代码在微控制器上运行,这意味着有一些限制我只有8 kb的ram,所以理想情况下我想在完成后立即删除对象。此外,我无法访问大多数标准库(没有Boost,STL等)。

所以我的问题是我应该如何解决这个问题?当我开始的时候,虽然我只是使用共享指针,但事实证明当一堆整数被添加到列表时并没有真正起作用。

3 个答案:

答案 0 :(得分:2)

垃圾收集总是有内存和CPU开销,所以在微控制器上你应该避免它。您可能想要使用的是简单的旧引用计数。适用于Objective-C,每个iPhone / iPad / iPod Touch应用程序都使用它和很多(大多数?)Mac应用程序。你这样做:

您的对象基类有一个整数,即引用计数器。一旦对象被分配,计数器就被设置为1.方法retain增加了计数器,方法release减少了计数器。一旦release使计数器达到0,就会调用解构函数并释放对象(释放)。

你必须小心避免保留周期,即在A< - >上保持彼此的对象。 B或A - > B - > C - > A然后,参考计数器不能降为0并且您有内存泄漏。 Apple通过命名和其他约定来解决这个问题(例如,如果一个对象有一个委托,那么委托永远不会被保留。)

引用计数的优点是它可能是最好的"垃圾收集"保持存储器尽可能低的方法。它的内存和CPU开销相当低。它的主要缺点是前面提到的参考周期是一个问题,你还需要在你的程序中明确保留/释放,因为语言不能猜到不是保留。

答案 1 :(得分:1)

我知道垃圾收集的两种常规机制:

  • 参考计数
  • Mark and Sweep

有各种风格/改进,更多地与实施策略(分代,复制,压缩......)相对应。

一般来说,参考计数最适合反应性(这里很重要),但是存在参考周期问题(取决于您的玩具语言语义)。

有一些复杂的算法来处理循环的收集,但更简单的解决方案是:

  • 使用参考计数进行在线维护
  • 每当内存达到定义的阈值以收集泄漏的周期时,执行完整的“Mark-And-Sweep”集合

答案 2 :(得分:1)

其他人提到了引用计数,它是循环依赖的问题。如果你想使用引用计数(如上所述快速响应),避免循环问题的一种方法是在所有地方使用值语义。如果您没有用户级别的指针/引用,那么您不必担心这些循环依赖项。

为了节省内存,你可能想要使用一些写时复制语义。即:

x = list('a','b','c','d')
y = x; 
// x and y point to the same list in memory
y.replace(2, 'e') 
// x and y point to different lists in memory
// those 2 lists share instances of 'a', 'b', and 'd'

如果你不使用像copy-on-write这样的东西,那么内存使用可以从值语义中迸发出来。