相信很有朋友在面试时大多会被问到 装箱 的问题,也是一个经典的问题,可深可浅,那今天我们就从 汇编内存 角度进行统一解读下。

为了方便演示,先上一段装箱的代码。

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_ni+0x142a8) (629e42a8)           // 获取编码类型
022e087e e845282ffe      call    005d30c8 (JitHelp: CORINFO_HELP_NEWSFAST)  //生成一个初始化类型放在 eax 中。(objheader+methodtable+占位符)
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 [eax+4],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复制到堆上区域。

可以看到,这里涉及到了如下几个性能开销。

  1. 内存分配

风险在于分配引发的gc回收概率,比如判代回收 (临时代,FullGC)。

  1. 多次内存复制 (stack -> heap -> register)

一个装箱就有 6 个mov,反复的在 ,,寄存器 之间交换。

  1. 增加 gc 回收压力

gc本来工作压力就很大,这又有无谓的分配,难哈。

最后就是如何解决,大概有如下两点。尽可能避免装箱 或者合理的使用 泛型

都说不要装箱,那装箱到底带来了什么开销?相关推荐

  1. Serverless:为我们到底带来了什么

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | Anycodes 来源 | 公众号「Go Se ...

  2. android 广播 7.0变化,安卓7.0到底带来了那些变化?

    原标题:安卓7.0到底带来了那些变化? 19号谷歌在它的I/O开发者大会上正式发布了全新的安卓7.0,那么新版本的安卓到底带来了哪些变化和改进呢?一起来看下吧! 一.性能提升 从安卓5.0开始,谷歌把 ...

  3. 计算机带来科技进步,科技的进步到底带来了什么

    科技的进步到底带来了什么 2011-05-27 23:09:14 这是个科学技术高速发展的时代,各国都在不遗余力的发展高科技,科学技术的水平已经成为了一个国家实力雄厚与否的一个标准.科技进步给人们生活 ...

  4. 程序员的梗_程序员都背着大书包,里面到底装的什么?程序员们:钱、电脑.....

    程序员的典型形象是什么?大概就是穿着格子衫.背着大书包的形象吧? 不明白为什么程序员都喜欢背着大书包,一位网友发出灵魂拷问:地铁上的程序员都背着大书包,里面到底装的什么? 程序员们翻了翻自己的大书包, ...

  5. 人人都在说的数字化,到底什么是数字化?

    人人都在说的数字化,到底什么是数字化? 我看了很多关于数字化的文章,发现大部分都在混淆术语,部分文章已经开始将数字化标记为数字化转型,以安抚管理层.获得项目批准或进行销售...... 所以这篇内容,我 ...

  6. 小学生都开始学的Python编程到底是什么?

    小学生都开始学的 Python编程到底是什么? Python 是一门有条理的和强大的面向对象的程序设计语言,Python 已经成为最受欢迎的程序设计语言之一,本文带你简单入门Python编程基础. 对 ...

  7. java装箱_Java装箱和拆箱

    自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象.自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接. 如 ...

  8. HDC.Cloud2021|开发者们都在谈的云原生到底长什么样?

    本文分享自华为云社区<HDC.Cloud2021|开发者们都在谈的云原生数据库是什么样的?>,原文作者:华为云头条. 近几年,云原生的风越刮越大,成为云计算领域炙手可热的话题.身为开发者, ...

  9. java中byte装箱和装箱_Java包装类、拆箱和装箱详解

    虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备"对象"的特性--不携带属性.没有方法可调用. 沿用它们只是为了迎合 ...

最新文章

  1. android文件存储token,ANDROID 学习笔记(二) 用户登陆问题 TOKEN SESSION 缓存
  2. 怎样检查python环境是否安装好_如何搭建pytorch环境的方法步骤
  3. Hibernate 事物隔离级别 深入探究
  4. php获取当前操作系统类型 PHP_OS
  5. OllyDbg笔记-初识PE文件(nag窗口破解)
  6. ubuntu无法打开Firefox
  7. 贪吃蛇python语言代码_Python贪吃蛇简单的代码
  8. shell之for循环的3个简单脚本
  9. Tensor is not an element of this graph 解决方法
  10. 将数据类型为列表中的内容复制粘贴到 SAP 或 Excel
  11. Collecting stars
  12. MATLAB 绘图笔记——绘制两端尖角colorbar
  13. 解决java.io.IOException: Cannot run program cygpath: CreateProcess error=2, 系统找不到指定的文件 的错误...
  14. Spark-SQL 多维度聚合优化
  15. Unity的Application.Quit()方法使用失效的其他解决方案。
  16. Python学习笔记-字符串相关
  17. redis_day_23_twitter/ twemproxy代理集群代理redis
  18. html右侧导航栏固定,固定导航栏.html
  19. 笨笨对面向对象的理解
  20. 单片机错误操作导致JLINK无法烧写程序no cortex-m sw device found

热门文章

  1. 1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列
  2. nagios监控mysql(check_mysql)及内存使用率(check_mem)
  3. 【转】2007高校BBS上20个睿智的冷笑话
  4. matlab光顺拐点,基于MATLAB的最大误差双圆弧逼近曲线的算法及实现.pdf
  5. python如何安装panda数据库_在Pycharm中安装Pandas库方法(简单易懂)
  6. Linux系统安装Appach 2.4.6
  7. 白白的(baibaide)
  8. virtualenv模块使用
  9. python简单开发接口
  10. 架构师速成4.6-软技能和硬技能