垃圾回收时发生的一个诡异问题 - 编程入门网
//new出来的对象地址
mov ecx,dword ptr [ebp-10h]
call dword ptr ds:[806DE8h] (Test_WinForm.GC_Test+tc..ctor(), mdToken: 0600004f)
mov eax,dword ptr [ebp-10h]
mov dword ptr [ebp-0Ch],eax //在栈上保存对象地址
call mscorlib_ni+0x6b7bcc (6c6a7bcc) (System.GC.Collect(), mdToken: 06000ab8) //强制垃圾回收
nop
call mscorwks!GCInterface::RunFinalizers (6cbe3491)
release下反汇编:
在这里要说明一点,虽然在强制调用gc前EAX中保存了tc的对象地址,但因为EAX这个寄存器只是方法调用后返回值的所以不能确保在这个寄存器的值不会被替换掉(通过跟踪GCInterface::CollectGeneration发现该函数一开始就把eax中的值替换掉了)。既然明白了垃圾回收时确定可达对象的原理我们就可以做一个小小的实验了,在强制垃圾后面加入这条语句:
这时在release下运行其运行结果就和debug下一样了必须要点击第二次才会执行析构函数,让我们再看看此时的反汇编:
我跟踪了整个gc函数发现虽然在函数体内替换了esi的值但是函数结束后esi的值被恢复了而eax的值是不会被恢复的,现在还不明白原理。实际上本文没有什么特别的东西只是证明了一下gc理论和jit优化的能力。 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |