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