struct对象可能被分配在托管堆上吗?

--会的。

比如当对struct装箱的时候,就会被分配在托管堆上。

比如,让一个struct实现一个接口。

    public interface IReport
    {
        string Name { get; }
    }

    public struct Score : IReport
    {
        public string Name
        {
            get { return "80分来自struct"; }
        }
    }

再来一个类负责打印接口属性值的类和方法。

   public class Tester
    {
        public void Test(IReport report)
        {
            Console.WriteLine(report.Name);
        }
    }

然后在Main方法中如下调用:

        static void Main(string[] args)
        {
            var tester = new Tester();
            tester.Test(new Score());
            Console.ReadKey();
        }

现在,我们想查看在这过程中,struct是否发生了装箱。

打开"VS2012开发人员命令提示"。

导航到exe文件所在的文件夹,然后用ildasm反编译,把IL代码输出到一个1.txt文件中。

我们看到,对struct对象进行了装箱。

那么,如何避免装箱呢?

可以在Tester类中,增加一个泛型方法。

   public class Tester
    {
        public void Test(IReport report)
        {
            Console.WriteLine(report.Name);
        }

        public void TestGeneric<T>(T report) where T : IReport
        {
            Console.WriteLine(report.Name);
        }
    }

然后在Main方法中使用泛型方法。

        static void Main(string[] args)
        {
            var tester = new Tester();
            tester.TestGeneric(new Score());
            Console.ReadKey();
        }

再次运行,再次反编译,查看IL代码:

我们发现,struct已不再装箱。

Why?

在泛型方法中限定了方法参数的类型,struct满足类型的要求。当把struct对象作为实参传入时,泛型方法直接使用struct,而不是IReport,从而避免了struct的装箱。

struct对象可能分配在托管堆上吗的更多相关文章

  1. Java中对象并不是都在堆上分配内存的

    转(https://blog.51cto.com/13906751/2153924) 前段时间,给星球的球友们专门码了一篇文章<深入分析Java的编译原理>,其中深入的介绍了Java中的j ...

  2. "每日一道面试题".net托管堆是否会存在内存泄漏的情况

    首先说答案:会 所谓的内存泄漏,就是指内存空间上产生了不再被实际使用却又无非被分配的对象.严格意义上来说,在.net中经常会遇到内存泄漏的情况,因为托管堆内的对象不再被使用时,需要等待下一次GC才会被 ...

  3. 【性能优化】面试官:Java中的对象都是在堆上分配的吗?

    写在前面 从开始学习Java的时候,我们就接触了这样一种观点:Java中的对象是在堆上创建的,对象的引用是放在栈里的,那这个观点就真的是正确的吗?如果是正确的,那么,面试官为啥会问:"Jav ...

  4. .Net 类型、对象、线程栈、托管堆运行时的相互关系

    JIT(just in time)编译器 接下来的会讲到方法的调用,这里先讲下JIT编译器.以CLR书中的代码为例(手打...).以Main方法为例: static void Main(){ Cons ...

  5. 类型,对象,线程栈,托管堆在运行时的关系,以及clr如何调用静态方法,实例方法,和虚方法(第二次修改)

    1.线程栈 window的一个进程加载clr.该进程可能含有多个线程,线程创建的时候会分配1MB的栈空间. 如图: void Method() { string name="zhangsan ...

  6. 【.Net基础一】 类型、对象、线程栈、托管堆运行时的相互关系

    目前在看CLR via C#,把总结的记下来,索性就把他写成一个系列吧. 1.[.Net基础一] 类型.对象.线程栈.托管堆运行时的相互关系 2.[.Net基础二]浅谈引用类型.值类型和装箱.拆箱 J ...

  7. C# 类型、对象、线程栈和托管堆在运行时的关系

    我们将讨论类型.对象.线程栈和托管堆在运行时的相互关系,假定有以下两个类定义: internal class Employee    {        public int GetYearsEmplo ...

  8. 只能在堆上生成的对象 VS. 只能在栈上生成的对象

    1. 只能在堆上 即禁止在栈上生成.如何实现? 当对象建立在栈上面时,是由编译器分配内存空间的,调用构造函数来构造栈对象.如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存. 所以,只需 ...

  9. C#托管堆对象实例包含什么

    每个托管堆上的对象实例除了包含本身的值外,还包括:○ Type Object Ponter: 指向Type对象实例.如果是同类型的对象实例,就指向同一个Type对象实例.○ Sync Block In ...

随机推荐

  1. elasticsearch安装ik分词器(极速版)

    简介:下面讲有我已经打包并且编辑过的zip包,你可以在下面下载即可. 1.下载zip包.elasticsearch-analysis-ik-1.8.0.jar下面有附件链接[ik-安装包.zip],下 ...

  2. 常用Javascript集锦【不定期更新】

    怎样用javascript删除某个HEML标签 document.getElementById(id).parentNode.removeChild(document.getElementById(i ...

  3. DEEP COMPRESSION小记

    2016ICLR最佳论文 Deep Compression: Compression Deep Neural Networks With Pruning, Trained Quantization A ...

  4. MySQL的架构模型

    看到大牛用户DB架构部的Keithlan<数据库性能优化之查询优化>,在学习过程发现很多不错的东西,就把它保存下来,分享给大家,因为作者说了一句很经典的话:“if you want to ...

  5. nodejs mysql 执行多条sql语句

    执行多条查询语句 为了安全起见,默认情况下是不允许执行多条查询语句的.要使用多条查询语句的功能,就需要在创建数据库连接的时候打开这一功能: var connection = mysql.createC ...

  6. 方法调用---springMVC中调用controller的方法

    我们有一个路由StudentController,里面有一个方法count().如果要在另外一个GradeController中调用count()方法有2种方式: 因为StudentControlle ...

  7. django用户系统的测试,蛮不错的。

    https://blog.csdn.net/orangleliu/article/details/51944758 这个很实用 https://www.cnblogs.com/yanhuidj/p/1 ...

  8. 【LOJ】#2268. 「SDOI2017」苹果树

    题解 显然权值都是正的,我们最深的那个点一定延伸到了某个叶子 我们抛去这条链之外再选K个点即可 如果直接对一棵树选K个点,满足这样的依赖关系,可以通过一个后序遍历的顺序做出来 转移方法是 \(dp[i ...

  9. CentOS 7 之安装 Oracle 11gR2

    一.准备工作 1.下载Oracle安装包:linux.x64_11gR2_database_1of2.zip 和 linux.x64_11gR2_database_2of2.zip ,可以下载到本地, ...

  10. 【Java】链表中存储对象的问题

    更新: 在一次搜索“变量声明在循环体内还是循环体外”问题时,碰见了一个这样的代码,与本文类似,代码如下: Document [] old ......//这是数据源 EntityDocument[] ...