垃圾收集的想法

Ideas for Garbage Collection

本文关键字:      更新时间:2023-10-16

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

所以我的问题是我应该如何解决这个问题?当我开始的时候,我想我只会使用共享指针,但结果并不是真的工作,当一堆整数被添加到一个列表

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

对象基类有一个整数,即引用计数器。一旦对象被分配,计数器就被设置为1。有一个方法retain可以增加计数器还有一个方法release可以减少计数器。一旦release使计数器达到0,就调用解构函数,对象被释放。

你必须小心避免保留循环,即对象彼此保留为A <-> B或A -> B -> C -> A,然后引用计数器不能降为0,你会有内存泄漏。苹果通过命名和其他约定来解决这个问题(例如,如果一个对象有一个委托,这个委托永远不会被保留)。

引用计数的优点是,它可能是保持内存尽可能低的最好的"垃圾收集"方法。它的内存和CPU开销相当低。它的主要缺点是前面提到的引用循环是一个问题,并且您还需要在程序中显式地保留/释放,因为语言将无法猜测何时不保留

我知道两种一般的垃圾收集机制:

  • 引用计数
  • 标记和扫描

有各种各样的风格/改进,更符合实现策略(分代,复制,压缩,…)。

一般来说,引用计数对于反应性是最好的(这在这里很重要),但是存在引用循环的问题(取决于您的玩具语言语义)。

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

  • 使用参考计数在线维护
  • 每当内存达到定义的阈值时,执行完整的"标记和清除"收集以收集泄漏周期

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

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

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'

如果您不使用诸如写时复制之类的东西,则内存使用可能会从值语义中飙升。

相关文章:
  • 没有找到相关文章