6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱[转]
引言
本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱。文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆;最后介绍值类型和引用类型,并说明一些有关它们的重要原理。
最后通过一个简单的示例代码说明装箱拆箱带来的性能损耗。
声明变量的内部机制
在.NET程序中,当你声明一个变量,将在内存中分配一块内存。这块内存分为三部分:1,变量名;2,变量类型;3,变量值。
下图揭示了声明一个变量时的内部机制,其中分配的内存类型依据你的变量类型。.NET中有两种类型的内存:栈内存和堆内存。在接下来的内容中,我们会了解到这两种类型的详细内容。
栈和堆
为了明白什么是栈和堆,先让我们看下下面示例代码的内部机制:
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概念:栈,堆,值类型,引用类型,装箱,拆箱[转]相关推荐
- 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱
引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...
- 栈,堆,值类型,引用类型,装箱,拆箱 .NET中 6个重要的概念
== 转载于:https://www.cnblogs.com/xiao-hei/p/3847525.html
- 栈和托管堆/值类型和引用类型/强制类型转换/装箱和拆箱[C#]
一.栈和托管堆 通用类型系统(CTS)区分两种基本类型:值类型和引用类型.它们之间的根本区别在于它们在内存中的存储方式..NET使用两种不同的物理内存块来存储数据-栈和托管堆.如下图所示: 值 ...
- 堆和栈、值类型与引用类型、装箱与拆箱
堆栈:内存条里的某一块. 电脑中有6个地方可以保存数据. <1>寄存器:保存最快.这东西在处理器内部.也就是CPU里的一小块地方给你放数据.既然是CPU,那么主要工作是计算,所以这块寄存器 ...
- 值类型 引用类型 堆栈 堆 之 异想
看了很多值类型 和 引用类型的文章(谷歌能搜索出来的) 看了越多疑问越大,而这些资料中没有具体的说明. 问题: 1.堆栈 和 堆 分别存于计算机的哪个硬件(CPU缓存,内存,硬盘)? 2.为什么只有值 ...
- 第十七节:易混淆的概念(静态和非静态、拆箱和装箱)
一. 静态和非静态 1. 概念介绍 ① 静态类(被static修饰) vs 普通类(没有被static修饰) ② 静态成员:被static修饰的成员,比如:静态方法.静态字段等 ③ 普通成员(实例成 ...
- 六个重要的.NET概念:栈、堆、值类型、引用类型、装箱和拆箱
目录 介绍 当你声明一个变量时,里面有什么? 栈和堆 值类型和引用类型 那么哪些数据类型是引用类型,哪些是值类型? 装箱和拆箱 装箱和拆箱的性能含义 关于源代码 下载源代码 - 42.5 KB 介绍 ...
- 转:图解C#的值类型,引用类型,栈,堆,ref,out
C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C#程序员都会接触到的概念,也是C#程序员面试经常考到的知识,随便搜搜 ...
- .NET六大剑客:栈、堆、值类型、引用类型、装箱和拆箱
.NET六大剑客:栈.堆.值类型.引用类型.装箱和拆箱 一."堆","栈"专区 这两个字我相信大家太熟悉了,甚至于米饭是什么?不知道..."堆&quo ...
- C# 装箱和拆箱、理论概念(非原创)
注意:在装箱的过程中,会新生成一个堆(托管堆)对象,他值类型的值复制到引用类型(堆对象)中,此后,值类型变量的更改,不会影响引用类型.在拆箱时,会生成一个新的堆栈类型变量,将引用类型的值复制到值类型( ...
最新文章
- Mysql数据库事务详解
- Java中导入错误的jar所引发的问题
- 嵌入式学习路线怎么学,如何学习嵌入式系统
- labview实例_手把手以实例教你学LabVIEW编程,事件结构框架
- LeetCode 117. 填充每个节点的下一个右侧节点指针 II(递归循环)
- android netty导入_Android Netty框架的使用
- python预测股票价格_python用线性回归预测股票价格
- 九、Linux的网络配置
- IP属地信息哪里来的?手把手教你实现通过IP查询属地信息
- 【阿狸的小伙伴win7主题】
- match函数的用法
- Exercise39: python字典(访问,操作,list(), dirt.items(), dirt.get() )
- lattice planner 规划详解
- 买房税费大攻略!哪些费用必须交?
- javascript 压缩_14种用于压缩JavaScript的工具
- 未群发消息接腾讯服务器吗,腾讯企业QQ(协同)如何设置并群发消息?
- 【书谷】一个免费赠送图书的好网站,推荐给书虫们
- 空洞卷积(Dilated Convolutions)
- 华为鸿蒙应用名称,国产自主系统名字定了 华为鸿蒙商标已注册公告
- 我们是如何改进YOLOv3进行红外小目标检测的?
热门文章
- 基于SSM的猫头鹰轻博客系统
- MyBatis工作流程及配置
- Filebeat 5.x 日志收集器 安装和配置
- webapi 状态返回 php,让WebAPI 返回JSON格式的数据实例教程
- java mvc 登陆_SpringMVC实现用户登录实例
- 阶段3 3.SpringMVC·_06.异常处理及拦截器_4 SpringMVC拦截器之介绍和搭建环境
- python正则表达式练习题
- 网站的动静分离实践(动静分离)
- 组合模式Composite
- Ruby代码块(Block)