阿里云1m宽带做网站卡吗,脑子笨适合学计算机吗,网站免费高清素材软件小游戏,如何开网上商城相信很有朋友在面试时大多会被问到 装箱 的问题#xff0c;也是一个经典的问题#xff0c;可深可浅#xff0c;那今天我们就从 汇编 和 内存 角度进行统一解读下。为了方便演示#xff0c;先上一段装箱的代码。class Program{static void Main(string[] args){var i 10;va… 相信很有朋友在面试时大多会被问到 装箱 的问题也是一个经典的问题可深可浅那今天我们就从 汇编 和 内存 角度进行统一解读下。为了方便演示先上一段装箱的代码。class Program{static void Main(string[] args){var i 10;var o (object)i;Console.ReadLine();}}接下来用 windbg 看一下它的汇编代码。0:000 !U /d 022e089a
Normal JIT generated code
ConsoleApp1.Program.Main(System.String[])
Begin 022e0848, size 5bD:\net5\ConsoleApp1\ConsoleApp1\Program.cs 15:
022e0872 c745f80a000000 mov dword ptr [ebp-8],0AhD:\net5\ConsoleApp1\ConsoleApp1\Program.cs 17:
022e0879 b9a8429e62 mov ecx,offset mscorlib_ni!System.Text.Encoding.GetEncodingCodePage(Int32)$##6006719 PERF (mscorlib_ni0x142a8) (629e42a8) // 获取编码类型
022e087e e845282ffe call 005d30c8 (JitHelp: CORINFO_HELP_NEWSFAST) //生成一个初始化类型放在 eax 中。objheadermethodtable占位符
022e0883 8945f0 mov dword ptr [ebp-10h],eax //备份地址到 栈中
022e0886 8b45f0 mov eax,dword ptr [ebp-10h] //恢复 eax 值
022e0889 8b55f8 mov edx,dword ptr [ebp-8] //将 0A 赋给 edx 上
022e088c 895004 mov dword ptr [eax4],edx //将 edx 赋给 this.x 位置
022e088f 8b45f0 mov eax,dword ptr [ebp-10h] //提取栈值到 eax 值
022e0892 8945f4 mov dword ptr [ebp-0Ch],eax //将eax赋值给变量 o因为每句汇编代码都有注释我就不解释了这里主要看一下 CORINFO_HELP_NEWSFAST方法它是干什么的呢这得从源码说起/* Allocating a new object. Always use ICorClassInfo::getNewHelper() to decide which is the right helper to use to allocate an object of a given type. */CORINFO_HELP_NEW_CROSSCONTEXT, // cross context new objectCORINFO_HELP_NEWFAST,CORINFO_HELP_NEWSFAST, // allocator for small, non-finalizer, non-array objectCORINFO_HELP_NEWSFAST_FINALIZE, // allocator for small, finalizable, non-array objectCORINFO_HELP_NEWSFAST_ALIGN8, // allocator for small, non-finalizer, non-array object, 8 byte alignedCORINFO_HELP_NEWSFAST_ALIGN8_VC,// allocator for small, value class, 8 byte alignedCORINFO_HELP_NEWSFAST_ALIGN8_FINALIZE, // allocator for small, finalizable, non-array object, 8 byte alignedCORINFO_HELP_NEW_MDARR, // multi-dim array helper (with or without lower bounds - dimensions passed in as vararg)CORINFO_HELP_NEW_MDARR_NONVARARG,// multi-dim array helper (with or without lower bounds - dimensions passed in as unmanaged array)CORINFO_HELP_NEWARR_1_DIRECT, // helper for any one dimensional array creationCORINFO_HELP_NEWARR_1_R2R_DIRECT, // wrapper for R2R direct call, which extracts method table from ArrayTypeDescCORINFO_HELP_NEWARR_1_OBJ, // optimized 1-D object arraysCORINFO_HELP_NEWARR_1_VC, // optimized 1-D value class arraysCORINFO_HELP_NEWARR_1_ALIGN8, // like VC, but aligns the array startCORINFO_HELP_STRCNS, // create a new string literalCORINFO_HELP_STRCNS_CURRENT_MODULE, // create a new string literal from the current module (used by NGen code)可以看到CORINFO_HELP_NEWSFAST 是用于分配 小对象无终结器非数组 的专用方法也属于高效的 快速分配路径那分配完之后的初始化长什么样子呢这就需要用 windbg 下断点调试从汇编代码看最后的结果会存放在 eax 上 如下图所示最后将栈上的10复制到堆上区域。可以看到这里涉及到了如下几个性能开销。内存分配风险在于分配引发的gc回收概率比如判代回收 (临时代FullGC)。多次内存复制 stack - heap - register一个装箱就有 6 个mov反复的在 栈,堆,寄存器 之间交换。增加 gc 回收压力gc本来工作压力就很大这又有无谓的分配难哈。最后就是如何解决大概有如下两点。尽可能避免装箱 或者合理的使用 泛型。