原文
class GCAllocated {
float[] data;
this() {
// 非垃集分配字段
this.data = cast(float[])(core.stdc.stdlib.malloc(nBytes)[0 .. nBytes]);
}
}
void foo() {
auto obj = new GCAllocated(); // 垃集分配
...
}float[]不包含指针,因此GC闲着.
扫描时,GC会看到data.ptr指针,但不会扫描它的区域,因为它不在GC区间内(运行时可区分托管指针和其他指针).
扫描后,如果obj不可访问时,GC析构它,但这不会回收data.ptr,因为它知道它不拥有它.
在D中,切片的所有权完全由它指向的内存区域决定.
如果指向GC内存,则它就是GC切片.
简短回答:是的,GC闲着.
长答案:即使GC想干啥,又怎么可能呢?它没有如何分配的信息.就GC而言,就像其他数组,它只是指针+大小对,且指针恰好指向GC分配内存之外.除此外,GC对指针一无所知.是malloc分配的吗?是静态内存吗?用户自定义分配器吗?随机垃圾值吗?谁知道.GC对指针一无所知,因此保守地忽略它.
D的GC是保守的,即如果对齐指针大小值可能是指针,则GC会小心假设它*是*指针值,并标记指向GC内存的为活动指针.值可以是int或long,GC不知道.(不过,最近的精确实现可能会跳过一些误报.)同样原则也适用:如果指针有GC不知道的值(即,未知的GC块),则GC保守地忽略它.
void[]可能包含指针,float[]不包含,因此不会扫描它.或至少不应.因而尽量少用void[].
void main()
{
import std.stdio;
auto voidArray = typeid(void[]);
auto floatArray = typeid(float[]);
writeln(voidArray.next.flags() & 1 );
writeln(floatArray.next.flags() & 1);
}










