如何让Lisp垃圾收集器在我的类槽中删除外部c ++分配的内存?

时间:2017-08-19 07:46:31

标签: garbage-collection common-lisp finalizer

我的班级看起来像这样:

(defclass matrix ()
  ((rows :initarg :rows :initform 2)
   (cols :initarg :cols :initform 2)
   (matrix :accessor matrix)))

我有一个initialize-instance方法的专门化,它通过调用c ++库为矩阵槽创建对象。我有一个matrix-destroy函数,它将释放用c ++分配的内存。

我想要的是能够让垃圾收集器在矩阵槽上调用matrix-destroy。在普通的lisp中有没有惯用的方法呢?

1 个答案:

答案 0 :(得分:3)

为了在垃圾收集器收集对象后运行函数,您需要为该对象设置终结器。 Common Lisp标准不包括终结器,但实现确实提供了它们。有一个名为Trivial Garbage的兼容性库,您可以使用它来移植它们。

只需在要将终结器附加到的对象上调用FINALIZE即可设置终结器。终结器函数不能包含对对象本身的任何引用,因为这将阻止它被收集。您还应该记住,终结器可以在任何线程中随时执行,因此它应该是可重入的,而不是依赖于任何特定的动态环境。

SBCL手册在7.4 Garbage Collection中有一个简短的终结器示例。您还可以看到一些使用它们的现有项目,例如cl-sdl2,它们使用它们来释放SDL曲面,纹理等。有关设置终结器的位置,请参见SDL-COLLECT,有关SDL-COLLECT的调用位置示例,请参见CREATE-RGB-SURFACE