我在 Mono 的网页上读到他们在精确模式下使用 Boehm GC。我也将 Boehm GC 与 C++ 一起使用,但是,我在其文档或标题中没有发现任何指示精确模式的内容,更不用说如何打开它了。
任何信息是否默认情况下实际上具有精确模式以及如何打开它,或者它只是 Mono 开发人员的某种修改?
我在 Mono 的网页上读到他们在精确模式下使用 Boehm GC。我也将 Boehm GC 与 C++ 一起使用,但是,我在其文档或标题中没有发现任何指示精确模式的内容,更不用说如何打开它了。
任何信息是否默认情况下实际上具有精确模式以及如何打开它,或者它只是 Mono 开发人员的某种修改?
Mono 下 Boehm GC 中的精确模式不仅仅是GC_MALLOC_ATOMIC
. 这仅适用于基本类型的数组。
对于托管类型,GC_gcj_malloc
使用。Mono 的编译器为每个托管类型生成一个对象描述符,然后它只需GC_gcj_malloc
使用大小参数和指向托管类型描述符的指针进行调用。Boehm GC 然后在标记阶段引用描述符以跟踪托管指针。
您最终只会将根指针作为原始指针放在堆栈上(GC_gcj_malloc
返回 void* 并且无法通过 GC 收集之前的某种堆栈描述符告诉 GC 指针在堆栈上的位置)。这就是 Mono(在 SGen 之前)说他们以保守模式扫描堆栈的原因。
如果您想在 C++ 下实现这一点,您将无法简单地依赖 C++ 编译器为您生成对象描述符。我很久以前的设想是编写一个中间编译器,它解析你所有的 C++ 头文件以查找已标记为托管类的类定义(例如_ref class MyManagedObject
,在哪里_ref
简单地#define
为空),并生成一个包含这些对象描述符的头文件。然后,您将使用GC_make_descriptor
andGC_malloc_explicitly_typed
函数以精确模式分配对象,而不是GC_gcj_malloc
因为您无法控制 C++ 编译器如何分配其 vtable。
*编辑:请参阅GCC 的托管 C++(开源 GPL v3)。
垃圾收集器(此处存档)的文件 doc/gcinterface.html 指出:
void * GC_MALLOC_ATOMIC(size_t nbytes) 分配 nbytes 的存储空间。需要与 nbytes 成比例的(摊销)时间。结果对象在未引用时将自动释放。客户端承诺生成的对象永远不会包含任何指针。内存没有被清除。这是分配字符串、浮点数组、位图等的首选方式。有关指针位置的更精确信息可以使用分发中的 gc_typed.h 中的接口传递给收集器。
看起来有一个可以使用的“精确”界面。
我相信精确模式需要编译器的支持才能准确指示指针的存储位置。C 和 C++ 中的类型转换使得这几乎是不可能的。
具有内置反射的托管语言将使这变得容易得多。