D GC.collect()对象可达性

D GC.collect()对象可达性,d,D,没有更多引用的对象不能通过GC.collect()立即进行垃圾回收,但是,对new、writeln或Thread.sleep等的中间调用将使未引用的对象可以通过GC.collect()进行访问 导入标准stdio; 导入core.thread; 导入核心内存; C类 { 字符串m_str; 此(字符串s){this.m_str=s;} ~this(){writeln(“析构函数:,this.m_str);} } void main() { { C c1=新的C(“c1”); } { C c

没有更多引用的对象不能通过GC.collect()立即进行垃圾回收,但是,对new、writeln或Thread.sleep等的中间调用将使未引用的对象可以通过GC.collect()进行访问

导入标准stdio;
导入core.thread;
导入核心内存;
C类
{
字符串m_str;
此(字符串s){this.m_str=s;}
~this(){writeln(“析构函数:,this.m_str);}
}
void main()
{
{
C c1=新的C(“c1”);
}   
{
C c2=新的C(“c2”);
}
//writeln(“添加此writeln意味着c2在第一次GC.collect时被破坏。”);
//Thread.sleep(1);//类似地,此调用意味着c2在第一次GC.collect时被破坏。

//int x=0;for(int i=0;i我不熟悉D的垃圾收集的细节,但一般的技术是从所有“根指针”开始,找出哪些对象是活动的。当事情被编译成机器代码时,这意味着从函数调用堆栈和CPU寄存器开始

上面的代码可能会编译成以下代码:

$r0 = new C("c1")
$r0 = new C("c2")
GC.collect()
writeln("Running second round GC.collect")
GC.collect()
writeln("Exiting...")
当第一个
GC.collect()
时,没有更多对第一个对象的引用(因为
$r0
被覆盖)。即使没有使用第二个对象,在
$r0
中仍然有指向它的指针,因此GC保守地假设它是可访问的。请注意,编译器可以在变量
c2
超出范围后清除
$r0
,但这会使代码运行较慢


当第一个
writeln
调用执行时,它可能在内部使用register
$r0
,因此它清除对第二个对象的引用。这就是第二次调用
GC.collect()后回收第二个对象的原因

忘了提一下,上面的代码是在windows 32位dmd.2.052上的,没有编译器标志。请注意,由于D GC是保守的,它不能保证收集到任何未引用的对象。非常感谢您的回答,在我提出以下关于什么代码可以安全地保存在de中的问题之前,这是一个先决条件结构者。
$r0 = new C("c1")
$r0 = new C("c2")
GC.collect()
writeln("Running second round GC.collect")
GC.collect()
writeln("Exiting...")