当前位置: 首页 > news >正文

校园网站建设合同百度文库代理网址网站

校园网站建设合同百度文库,代理网址网站,网站建设有什么理论依据,学校网站信息化建设工作心得经常在代码中看到有人将 null 赋值给引用类型#xff0c;来达到让 GC 提前回收的目的#xff0c;这样做真的有用吗#xff1f;今天我们就来研究一下。为了方便讲解#xff0c;来一段测试代码#xff0c;提前将 test1null #xff0c;然后调用 GC.Collect() 看看是否能提前… 经常在代码中看到有人将 null 赋值给引用类型来达到让 GC 提前回收的目的这样做真的有用吗今天我们就来研究一下。为了方便讲解来一段测试代码提前将 test1null 然后调用 GC.Collect() 看看是否能提前回收。平台采用: .net5public class Program{static void Main(string[] args){ProcessRequest();}static void ProcessRequest(){var test1  new Test() { a  10 };Console.WriteLine($query.a{test1.a});var test2  new Test() { a  11 };Console.WriteLine($query.a{test2.a});//提前释放test1  null;var test3  new Test() { a  12 };Console.WriteLine($query.a{test3.a});GC.Collect();Console.WriteLine(垃圾回收啦);Console.ReadLine();}}public class Test{public int a;}接下来我们从 Debug 和 Release 两种模式下观察。一Debug 模式 要找到这个答案我们用 windbg 附加一下找到 test1 然后用 !gcroot 查看下引用即可。0:000 !clrstack -a OS Thread Id: 0x4dd0 (0) Child SP       IP Call Site 0057F2A4 79863539 System.Console.ReadLine() [/_/src/System.Console/src/System/Console.cs  463] 0057F2AC 04c405d1 ConsoleApp1.Program.ProcessRequest() [D:\net5\ConsoleApp2\ConsoleApp1\Program.cs  37]LOCALS:0x0057F2D4  0x000000000x0057F2D0  0x0283cd540x0057F2CC  0x0283cd900:000 !dumpheap -type TestAddress       MT     Size 0283a7c0 04c39008       12      0283cd54 04c39008       12      0283cd90 04c39008       12     0:000 !gcroot 0283a7c0 Thread 4dd0:0057F2AC 04C405D1 ConsoleApp1.Program.ProcessRequest() [D:\net5\ConsoleApp2\ConsoleApp1\Program.cs  37]ebp14: 0057f2c8-  0283A7C0 ConsoleApp1.TestFound 1 unique roots (run !gcroot -all to see all roots).是不是很惊讶test1 虽被赋 null但并没有被 GC.Collection 所回收原因在于 test1 被栈中的 ebp14 位置所持有那这个位置是咋回事我们反编译下代码看看简化后如下0:000 !U 04C405D1 Normal JIT generated code ConsoleApp1.Program.ProcessRequest() ilAddr is 0268205C pImport is 052FB030 Begin 04C40488, size 154D:\net5\ConsoleApp2\ConsoleApp1\Program.cs  22: 04c404aa b90890c304      mov     ecx,4C39008h (MT: ConsoleApp1.Test) 04c404af e8182c9afb      call    005e30cc (JitHelp: CORINFO_HELP_NEWSFAST) 04c404b4 8945ec          mov     dword ptr [ebp-14h],eax 04c404b7 8b4dec          mov     ecx,dword ptr [ebp-14h] 04c404ba ff152890c304    call    dword ptr ds:[4C39028h] (ConsoleApp1.Test..ctor(), mdToken: 06000004) 04c404c0 8b4dec          mov     ecx,dword ptr [ebp-14h] 04c404c3 c741040a000000  mov     dword ptr [ecx4],0Ah 04c404ca 8b4dec          mov     ecx,dword ptr [ebp-14h] 04c404cd 894df8          mov     dword ptr [ebp-8],ecxD:\net5\ConsoleApp2\ConsoleApp1\Program.cs  29: 04c4055c 33c9            xor     ecx,ecx 04c4055e 894df8          mov     dword ptr [ebp-8],ecx虽然 !gcroot 上显示的是 ebp14反向就是 ebp-14仔细看上面的汇编代码可以发现 test1 实例被放在了 ebp-14 和 ebp-8 两个栈位置而 test1null 只是抹去了 ebp-8 的栈单元所以它能被回收的时机只能是等 ProcessRequest() 方法销毁之后这也就是 Debug 模式下的 方法作用域应该是为了 Debug 调试用的从 gcinfo 上也可以看出来ebp-14 是禁止被GC跟踪的内部用途的栈单元。0:000 !U -gcinfo 04C405D1 Normal JIT generated code ConsoleApp1.Program.ProcessRequest() ilAddr is 0268205C pImport is 052FCA58 Begin 04C40488, size 154D:\net5\ConsoleApp2\ConsoleApp1\Program.cs  21:[EBP-08H] an untracked  local[EBP-0CH] an untracked  local[EBP-10H] an untracked  local[EBP-14H] an untracked  local[EBP-18H] an untracked  local[EBP-1CH] an untracked  local[EBP-20H] an untracked  local[EBP-24H] an untracked  local[EBP-28H] an untracked  local[EBP-2CH] an untracked  local[EBP-30H] an untracked  local二Release 模式 大家或许都知道 Release 是一种高度优化的激进模式我也很好奇在这种模式下 compile 或者  JIT 会做出怎么样的优化。1. 编译器层面的优化要寻找这个答案我们用 ILSpy 打开生成的 IL代码简化后如下.method private hidebysig static void ProcessRequest () cil managed {// Method begins at RVA 0x2058// Code size 144 (0x90).maxstack 3.locals init ([0] class ConsoleApp1.Test test1,[1] class ConsoleApp1.Test test2,[2] class ConsoleApp1.Test test3)IL_0050: ldnullIL_0051: stloc.0} // end of method Program::ProcessRequest从 idnull 上来看没有做任何优化居然直接翻译了哎。。。2. JIT优化查看 JIT 层面的优化只能看最终的汇编代码 和 托管堆 啦。0:000 !dumpheap -type TestAddress       MT     Size 02eaab38 02634b10       12      02ead344 02634b10       12      02ead380 02634b10       12     Statistics:MT    Count    TotalSize Class Name 02634b10        3           36 ConsoleApp1.Test Total 3 objects0:000 !U /d 0262549d Normal JIT generated code ConsoleApp1.Program.ProcessRequest() ilAddr is 025B2058 pImport is 04AFB108 Begin 02625370, size 131D:\net5\ConsoleApp2\ConsoleApp1\Program.cs  22: 02625370 55              push    ebp 02625371 8bec            mov     ebp,esp 0262538a b9104b6302      mov     ecx,2634B10h (MT: ConsoleApp1.Test) 0262538f e83cddfefd      call    006130d0 (JitHelp: CORINFO_HELP_NEWSFAST) 02625394 8945f0          mov     dword ptr [ebp-10h],eax 02625397 8b4df0          mov     ecx,dword ptr [ebp-10h] 0262539a e871f9ffff      call    02624d10 0262539f 8b4df0          mov     ecx,dword ptr [ebp-10h] 026253a2 c741040a000000  mov     dword ptr [ecx4],0Ah 026253a9 8b4df0          mov     ecx,dword ptr [ebp-10h] 026253ac 894dfc          mov     dword ptr [ebp-4],ecxD:\net5\ConsoleApp2\ConsoleApp1\Program.cs  29: 02625430 33c9            xor     ecx,ecx 02625432 894dfc          mov     dword ptr [ebp-4],ecx从汇编代码看Release 模式下也是采用双栈保存的也就是 方法级作用域。二可以得出结论了吗 至少在 .NET5 平台 Release 和 Debug 模式下的 test1 null; 是没有任何区别的其实这里有个问题 .NET5 下没区别不代表其他平台下也没有问题毕竟不同的 JIT 会作用不同的抉择接下来我们将同样的代码搬到 .NET Framework 4.5 下看看情况。1. .NET Framework 4.5 平台Debug 模式我们直接看托管代码0:006 !dumpheap -type TestAddress       MT     Size 02564bfc 00754ddc       12      02564c70 00754ddc       12     Statistics:MT    Count    TotalSize Class Name 00754ddc        2           24 ConsoleApp2.Test Total 2 objects居然是 2 个了那为什么会这样呢我们还是看下汇编。0:000 !U /d 023509a6 Normal JIT generated code ConsoleApp2.Program.ProcessRequest() Begin 02350880, size 187 D:\net5\ConsoleApp2\ConsoleApp2\Program.cs  21: 023508b1 b9dc4da200      mov     ecx,0A24DDCh (MT: ConsoleApp2.Test) 023508b6 e839286cfe      call    00a130f4 (JitHelp: CORINFO_HELP_NEWSFAST) 023508bb 8945ec          mov     dword ptr [ebp-14h],eax 023508be 8b4dec          mov     ecx,dword ptr [ebp-14h] 023508c1 ff15fc4da200    call    dword ptr ds:[0A24DFCh] (ConsoleApp2.Test..ctor(), mdToken: 06000004) 023508c7 8b45ec          mov     eax,dword ptr [ebp-14h] 023508ca c740040a000000  mov     dword ptr [eax4],0Ah 023508d1 8b45ec          mov     eax,dword ptr [ebp-14h] 023508d4 8945f8          mov     dword ptr [ebp-8],eax D:\net5\ConsoleApp2\ConsoleApp2\Program.cs  28: 0235097b 33d2            xor     edx,edx 0235097d 8955f8          mov     dword ptr [ebp-8],edx0:000 dp ebp-14h L1 0019f4e8  02472358 0:000 !do 02472358 Name:        ConsoleApp2.Test MethodTable: 00a24ddc EEClass:     00a21330 Size:        12(0xc) bytes File:        D:\net5\ConsoleApp2\ConsoleApp2\bin\Debug\ConsoleApp2.exe Fields:MT    Field   Offset                 Type VT     Attr    Value Name 637342a8  4000001        4         System.Int32  1 instance       10 a0:000 dp 0019f4e8 L1 0019f4e8  02472358 0:000 !do 02472358 Free Object Size:        24(0x18) bytes大家可以仔细看看输出内容虽然也是两个 栈位置 存放着 test1但GC做了不同的处理它无视 ebp-14 还牵引着 test1 的事实 ,直接将它标记为 free这就有点意思了。Release 模式我们直接用 !dumpheap -type Test 看托管堆。0:006 !dumpheap -type TestAddress       MT     SizeStatistics:MT    Count    TotalSize Class Name Total 0 objects居然发现不仅 test1 没有了test2,test3 都没有了。。。这就是所谓的 激进式回收。三结论 1.  .NET5 平台下Release 和 Debug 模式下设置 test1null 没有任何效果。2. .NET Framework 4.5 平台下Debug 模式下有效果可以起到 提前回收 的目的。Release模式下无效果GC会自动激进的回收所有后续未使用到的引用对象。3. 个人结论总的来说为了更好的平台兼容性如果想提前回收设置 test1 null; 是有一定效果的。
http://www.zqtcl.cn/news/565647/

相关文章:

  • 做网站字体大小网站建设是属于虚拟产品吗
  • 网站的内链怎么做校园网建设网站特色
  • 优化网站标题企业的网站一般做哪些维护
  • 聊天网站备案南阳定制网站制作价格低
  • 广州镭拓科技网站建设公司长春招聘
  • 视频网站app怎么做跨境贸易电子商务服务平台
  • 丽水网站seo餐饮vi设计案例
  • 娄底网站建设报价山东省住房和建设厅注册中心网站
  • 公司网站建设工作重点网站建设吉金手指专业11
  • vue做前台网站怎么做钓鱼网站吗
  • 个人建设网站如何定位烟台h5网站开发
  • 广州网站定制多少钱html5游戏开发
  • 使用angularjs的网站域名怎么解析到服务器
  • 地方门户网站盈利模式宝塔 wordpress
  • 西安网站备案软件开发基础教程
  • 有服务器做网站软件系统开发怎样容易
  • 网站建设的公司有发展吗织梦婚纱网站模板
  • 淘宝销售书网站建设方案wordpress调用评论数据
  • 搭建网站需要什么软件苏州吴中区建设局工程网站
  • 长沙市网站推广公司wordpress 弹窗登录插件
  • 网站策划怎么做内容朔州网站建设公司
  • 宁波拾谷网站建设蚌埠网站建设中心
  • 青岛专业设计网站公司加拿大广播公司
  • 盘锦市建设局网站地址八桂职教网技能大赛
  • 投资建设一个网站多少钱和淘宝同时做电商的网站
  • 做动物网站的素材icp备案 网站备案
  • 找人建网站唐山网络运营推广
  • 福建省住房建设厅网站6网站简历模板
  • 医疗网站模版杭州工商注册
  • 正保建设工程网站logo创意