垃圾收集的理念 我正在研究一种使用C++作为中间语言的玩具语言,目前它只支持三种类型的基类、整数、列表和lambda。所有函数都来回传递基类。编译后的代码运行在microcontoller上,这意味着存在某些限制,我只有8KB的ram,因此理想情况下,我希望在处理完对象后尽快将其删除。此外,我无法访问大多数标准库(无Boost、STL等)

垃圾收集的理念 我正在研究一种使用C++作为中间语言的玩具语言,目前它只支持三种类型的基类、整数、列表和lambda。所有函数都来回传递基类。编译后的代码运行在microcontoller上,这意味着存在某些限制,我只有8KB的ram,因此理想情况下,我希望在处理完对象后尽快将其删除。此外,我无法访问大多数标准库(无Boost、STL等),c++,c,garbage-collection,language-design,microcontroller,C++,C,Garbage Collection,Language Design,Microcontroller,所以我的问题是我应该如何解决这个问题?当我开始的时候,我想我只会使用共享指针,但事实证明,当一堆整数被添加到一个列表中时,这并不起作用。垃圾收集总是有内存和CPU开销,所以在微控制器上,你应该避免它。您可能希望使用的是简单的旧引用计数。Objective-C非常适用,每个iPhone/iPad/iPod Touch应用程序都使用Objective-C和很多(大多数?)Mac应用程序。你是这样做的: 对象基类有一个整数,即引用计数器。分配对象后,计数器设置为1。有一种方法retain增加计数器,还

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

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

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

您必须小心避免保留周期,即对象彼此保留在A B或A->B->C->A上,因为引用计数器不能降到0,并且您会有内存泄漏。Apple通过命名和其他约定解决了这一问题(例如,如果对象具有委托,则该委托永远不会保留)


引用计数的优点是,它可能是保持内存尽可能低的最佳“垃圾收集”方法。它的内存和CPU开销相当低。它的主要缺点是前面提到的引用周期是一个问题,您还需要在程序中显式保留/释放,因为语言无法猜测何时不保留。垃圾收集总是有内存和CPU开销,因此在微控制器上您应该避免它。您可能希望使用的是简单的旧引用计数。Objective-C非常适用,每个iPhone/iPad/iPod Touch应用程序都使用Objective-C和很多(大多数?)Mac应用程序。你是这样做的:

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

您必须小心避免保留周期,即对象彼此保留在A B或A->B->C->A上,因为引用计数器不能降到0,并且您会有内存泄漏。Apple通过命名和其他约定解决了这一问题(例如,如果对象具有委托,则该委托永远不会保留)


引用计数的优点是,它可能是保持内存尽可能低的最佳“垃圾收集”方法。它的内存和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'

如果不使用“写时复制”之类的方法,内存的使用可能会从值语义中激增。

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

It订单