引言

  本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱。文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆;最后介绍值类型和引用类型,并说明一些有关它们的重要原理。

  最后通过一个简单的示例代码说明装箱拆箱带来的性能损耗。

声明变量的内部机制

  在.NET程序中,当你声明一个变量,将在内存中分配一块内存。这块内存分为三部分:1,变量名;2,变量类型;3,变量值。

  下图揭示了声明一个变量时的内部机制,其中分配的内存类型依据你的变量类型。.NET中有两种类型的内存:栈内存和堆内存。在接下来的内容中,我们会了解到这两种类型的详细内容。

  

栈和堆

  为了明白什么是栈和堆,先让我们看下下面示例代码的内部机制:

view sourceprint?
1 public void Method1(){
2 // Line 1
3 int i=4;
4 // Line 2
5 int y=2;
6 //Line 3
7 class1 cls1 = new class1();
8 }

这里一共有3行代码。让我们一下逐行看一下它们是如何执行的:

第1行:当这行代码执行时,编译器为它分配一小块栈内存。运行时栈负责提供程序所需的内存;

第2行:程序继续执行。如同名字一样,栈在第一块内存的顶部分配了一块内存。你也可以认为是模块或零件一块一块叠起来;

    内存的分配与释放遵循后进先出(后进先出)逻辑,换句话说,内存只能在示例中i内存块的顶部分配或释放。

第3行:在第3行,我们创建了一个对象。当该行执行时,编译器在站上创建了一个指针,真实的对象存储在另一种叫“堆”的内存中。"堆"并不跟踪运行内存,它更像一堆随时可以访问的对象。堆用于动态分配内存。这里需要着重说明的是引用指针是分配在栈上。声明Class1 cls1时并不会给Class1的实例分配内存,而是分配一个栈变量cls1(并设置为null),然后把它指向“堆”。

退出方法:当方法退出时,它释放了栈上所有内存变量。换句话说,栈上所有的"Int"变量都依据后进先出的逻辑被释放掉了。要注意,此时不会释放堆内存,这种内存稍后会被“垃圾收集器”释放。

现在可能会有很多朋友奇怪为什么要分配2种内存,而不是仅用一种内存。

  如果仔细观察,你会发现基本类型并不复杂,他们值包含简单的值,如i=0。对象数据类型很复杂,它们会引用其它对象或基本类型。换句话说,它要保持其它多种多样的引用,而每种类型必须存在内存中。对象类型需要动态内存而基本类型需要静态内存。如果需要分配动态内存,那么就分配到堆上;反之在栈上。

值类型与引用类型

  现在我们明白了栈和堆,接下来看值类型和引用类型。值类型的数据和内存在同一个位置,而引用类型是一个指向内存的指针。

  下面示例是一个整形数据类型变量i被赋给另一个整形数据类型变量j。它们的内存值都分配在栈上。当我们把一个int值分配给另外一个int值时,需要创建一个完全不同的拷贝。换句话说,你可以改变其中任何一个而不会影响另外一个。这种数据类型被称为值类型。  当我们创建一个对象,并把一个对象赋给另外一个对象时,它们的指针指向相同的内存(如下图,当我们把obj赋给obj1时,它们指向相同的内存)。换句话说,我们改变其中一个,会影响到另外一个,这种类型称为引用类型。

那么那种类型是值类型和引用类型呢?

  在.NET中,依据数据类型,变量被分配到堆或栈上。“string”和"Object"是引用类型,其他基本类型被分配到栈上,是值类型,如下图:

装箱与拆箱

  通过上面学习,我们学到了很多有用的东西,其中最有用的是明白了当把数据从栈移动到堆上时会有性能损失。如下图实例,当我们把一个值类型装箱为引用类型时,数据从栈移动到堆上。反之,数据从堆移动到栈上。这种在堆和栈之间的移动带来了性能的损失。数据从值类型转变为引用类型的过程称为“装箱”,反之为“拆箱”。

如果编译上面的代码,在ILDASM中看IL代码就会发下如何进行装箱拆箱操作的,如下:

装箱拆箱的性能影响

  为了揭示装箱拆箱如何影响性能,我们把下面代码运行10000次。一个函数有装箱操作,另一个只有简单代码。我们用简单的计时器看它们的运行时间。装箱函数耗时 3542 MS,无装箱操作的耗时2477MS。这说明在实际项目中,除非必须,否则应避免装箱,拆箱操作。

备注:

  最近在CodeProject上看到<6 important .NET concepts: - Stack, heap, Value types, reference types, boxing and Unboxing>一文,个人觉得非常好,所以就翻一下给不想看英文的同学。由于能力有限,翻译的不好,望大家多多包涵。

来源:http://www.cnblogs.com/niyw/archive/2010/09/20/1832077.html

转载于:https://www.cnblogs.com/guangrou/archive/2010/09/24/1833833.html

6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱[转]相关推荐

  1. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱

    引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...

  2. 栈,堆,值类型,引用类型,装箱,拆箱 .NET中 6个重要的概念

    == 转载于:https://www.cnblogs.com/xiao-hei/p/3847525.html

  3. 栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#]

    一.栈和托管堆 通用类型系统(CTS)区分两种基本类型:值类型和引用类型.它们之间的根本区别在于它们在内存中的存储方式..NET使用两种不同的物理内存块来存储数据-栈和托管堆.如下图所示:     值 ...

  4. 堆和栈、值类型与引用类型、装箱与拆箱

    堆栈:内存条里的某一块. 电脑中有6个地方可以保存数据. <1>寄存器:保存最快.这东西在处理器内部.也就是CPU里的一小块地方给你放数据.既然是CPU,那么主要工作是计算,所以这块寄存器 ...

  5. 值类型 引用类型 堆栈 堆 之 异想

    看了很多值类型 和 引用类型的文章(谷歌能搜索出来的) 看了越多疑问越大,而这些资料中没有具体的说明. 问题: 1.堆栈 和 堆 分别存于计算机的哪个硬件(CPU缓存,内存,硬盘)? 2.为什么只有值 ...

  6. 第十七节:易混淆的概念(静态和非静态、拆箱和装箱)

    一. 静态和非静态 1. 概念介绍 ① 静态类(被static修饰) vs  普通类(没有被static修饰) ② 静态成员:被static修饰的成员,比如:静态方法.静态字段等 ③ 普通成员(实例成 ...

  7. 六个重要的.NET概念:栈、堆、值类型、引用类型、装箱和拆箱

    目录 介绍 当你声明一个变量时,里面有什么? 栈和堆 值类型和引用类型 那么哪些数据类型是引用类型,哪些是值类型? 装箱和拆箱 装箱和拆箱的性能含义 关于源代码 下载源代码 - 42.5 KB 介绍 ...

  8. 转:图解C#的值类型,引用类型,栈,堆,ref,out

    C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...

  9. .NET六大剑客:栈、堆、值类型、引用类型、装箱和拆箱

    .NET六大剑客:栈.堆.值类型.引用类型.装箱和拆箱 一."堆","栈"专区 这两个字我相信大家太熟悉了,甚至于米饭是什么?不知道..."堆&quo ...

  10. C# 装箱和拆箱、理论概念(非原创)

    注意:在装箱的过程中,会新生成一个堆(托管堆)对象,他值类型的值复制到引用类型(堆对象)中,此后,值类型变量的更改,不会影响引用类型.在拆箱时,会生成一个新的堆栈类型变量,将引用类型的值复制到值类型( ...

最新文章

  1. Mysql数据库事务详解
  2. Java中导入错误的jar所引发的问题
  3. 嵌入式学习路线怎么学,如何学习嵌入式系统
  4. labview实例_手把手以实例教你学LabVIEW编程,事件结构框架
  5. LeetCode 117. 填充每个节点的下一个右侧节点指针 II(递归循环)
  6. android netty导入_Android Netty框架的使用
  7. python预测股票价格_python用线性回归预测股票价格
  8. 九、Linux的网络配置
  9. IP属地信息哪里来的?手把手教你实现通过IP查询属地信息
  10. 【阿狸的小伙伴win7主题】
  11. match函数的用法
  12. Exercise39: python字典(访问,操作,list(), dirt.items(), dirt.get() )
  13. lattice planner 规划详解
  14. 买房税费大攻略!哪些费用必须交?
  15. javascript 压缩_14种用于压缩JavaScript的工具
  16. 未群发消息接腾讯服务器吗,腾讯企业QQ(协同)如何设置并群发消息?
  17. 【书谷】一个免费赠送图书的好网站,推荐给书虫们
  18. 空洞卷积(Dilated Convolutions)
  19. 华为鸿蒙应用名称,国产自主系统名字定了 华为鸿蒙商标已注册公告
  20. 我们是如何改进YOLOv3进行红外小目标检测的?

热门文章

  1. 基于SSM的猫头鹰轻博客系统
  2. MyBatis工作流程及配置
  3. Filebeat 5.x 日志收集器 安装和配置
  4. webapi 状态返回 php,让WebAPI 返回JSON格式的数据实例教程
  5. java mvc 登陆_SpringMVC实现用户登录实例
  6. 阶段3 3.SpringMVC·_06.异常处理及拦截器_4 SpringMVC拦截器之介绍和搭建环境
  7. python正则表达式练习题
  8. 网站的动静分离实践(动静分离)
  9. 组合模式Composite
  10. Ruby代码块(Block)