我正在研究一种使用C ++作为中间语言的玩具语言,目前它只支持三种类型,包括基类,整数,列表和lambda。所有函数都来回传递基类。编译代码在微控制器上运行,这意味着有一些限制我只有8 kb的ram,所以理想情况下我想在完成后立即删除对象。此外,我无法访问大多数标准库(没有Boost,STL等)。
所以我的问题是我应该如何解决这个问题?当我开始的时候,虽然我只是使用共享指针,但事实证明当一堆整数被添加到列表时并没有真正起作用。
答案 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)
我知道垃圾收集的两种常规机制:
有各种风格/改进,更多地与实施策略(分代,复制,压缩......)相对应。
一般来说,参考计数最适合反应性(这里很重要),但是存在参考周期问题(取决于您的玩具语言语义)。
有一些复杂的算法来处理循环的收集,但更简单的解决方案是:
答案 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这样的东西,那么内存使用可以从值语义中迸发出来。