快速业务通道

垃圾回收时发生的一个诡异问题 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-20
//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下反汇编:

mov   ebp,esp mov   ecx,7D6714h (MT: Test_WinForm.GC_Test+tc) call  mscorwks!JIT_NewFast (6cafc5d4)  //new tc() mov   dword ptr [eax+4],63h  //将99复制给对象地址+4(这里就是a的位置),相当于构造函数 xor   edx,edx lea   ecx,[edx-1] call  mscorwks!GCInterface::CollectGeneration (6cbbd082) call  mscorwks!GCInterface::RunFinalizers (6cbe3491) pop   ebp ret   4

在这里要说明一点,虽然在强制调用gc前EAX中保存了tc的对象地址,但因为EAX这个寄存器只是方法调用后返回值的所以不能确保在这个寄存器的值不会被替换掉(通过跟踪GCInterface::CollectGeneration发现该函数一开始就把eax中的值替换掉了)。既然明白了垃圾回收时确定可达对象的原理我们就可以做一个小小的实验了,在强制垃圾后面加入这条语句:

private void button1_Click(object sender,EventArgs e) { tc to=new tc(); GC.Collect(); GC.WaitForPendingFinalizers(); string s = tc.ToString(); return; }

这时在release下运行其运行结果就和debug下一样了必须要点击第二次才会执行析构函数,让我们再看看此时的反汇编:

mov   ebp,esp push  esi mov   ecx,7D6714h (MT: Test_WinForm.GC_Test+tc) call  mscorwks!JIT_NewFast (6cafc5d4) mov   esi,eax          //将对象地址赋值给esi mov   dword ptr [esi+4],63h xor   edx,edx lea   ecx,[edx-1] call  mscorwks!GCInterface::CollectGeneration (6cbbd082) call  mscorwks!GCInterface::RunFinalizers (6cbe3491) mov   ecx,esi         //将保存在esi中的值返回个ecx mov   eax,dword ptr [ecx] call  dword ptr [eax+28h]    //调用ToString() pop   esi pop   ebp ret   4

我跟踪了整个gc函数发现虽然在函数体内替换了esi的值但是函数结束后esi的值被恢复了而eax的值是不会被恢复的,现在还不明白原理。实际上本文没有什么特别的东西只是证明了一下gc理论和jit优化的能力。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号