目录

介绍

当你声明一个变量时,里面有什么?

栈和堆

值类型和引用类型

那么哪些数据类型是引用类型,哪些是值类型?

装箱和拆箱

装箱和拆箱的性能含义

关于源代码


  • 下载源代码 - 42.5 KB

介绍

本文将解释六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱。本文开始解释当您声明一个变量时内部会发生什么,然后继续解释两个重要的概念:栈和堆。然后,本文讨论了引用类型和值类型,并阐明了围绕它们的一些重要基础知识。

本文最后通过示例代码演示了装箱和拆箱对性能的影响。

图片取自http://michaelbungartz.wordpress.com/

当你声明一个变量时,里面有什么?

当您在.NET应用程序中声明一个变量时,它会在RAM中分配一些内存块。这个内存有三样东西:变量名、变量的数据类型和变量的值。

这是对内存中发生的事情的简单解释,但是根据数据类型,您的变量会分配到该类型的内存。内存分配有两种类型:栈内存和堆内存。在接下来的部分中,我们将尝试更详细地了解这两种类型的内存。

栈和堆

为了理解栈和堆,让我们了解下面代码内部实际发生的事情。

public void Method1()
{// Line 1int i=4;// Line 2int y=2;//Line 3class1 cls1 = new class1();
}

这是一个三行代码,让我们一行一行地了解内部是如何执行的。

内存分配和取消分配是使用LIFO(后进先出)逻辑完成的。换句话说,仅在内存的一端,即栈顶部分配和取消分配内存。

  • 1行:执行此行时,编译器会在栈中分配少量内存。栈负责跟踪应用程序所需的运行内存。
  • 2 :现在执行移动到下一步。顾名思义,栈是将这个内存分配堆叠在第一个内存分配之上。您可以将栈视为一系列放在彼此顶部的隔间或盒子。
  • 3行:在第3行中,我们创建了一个对象。执行此行时,它会在栈上创建一个指针,实际对象存储在称为“堆”的不同类型的内存位置中。“堆”不跟踪运行内存,它只是一堆可以随时访问的对象。堆用于动态内存分配。

这里要注意的更重要的一点是引用指针是在栈上分配的。该语句Class1 cls1;不为Class1的实例分配内存,它只分配一个栈变量cls1(并将其设置为null)。它运行到new关键字的时候,它在“堆”上分配。

退出方法(fun:现在终于执行控制开始退出方法。当它通过结束控制时,它清除所有分配在栈上的内存变量。换句话说,所有与int数据类型相关的变量都以“后进先出”方式从栈中解除分配。

捕获——它没有解除分配堆内存。垃圾收集器稍后将取消分配此内存。

现在很多开发者朋友一定很疑惑,为什么会有两种类型的内存,难道我们不能把所有的东西都分配到一种内存类型上就完成了吗?

如果仔细观察,原始数据类型并不复杂,它们包含像“int i = 0”这样的单个值。对象数据类型很复杂,它们引用其他对象或其他原始数据类型。换句话说,它们持有对其他多个值的引用,并且每个值都必须存储在内存中。对象类型需要动态内存,而原始类型需要静态类型内存。如果需要动态内存,则将其分配在堆上,否则将进入栈。

图片取自http://michaelbungartz.wordpress.com/

值类型和引用类型

现在我们已经了解了栈和堆的概念,是时候了解值类型和引用类型的概念了。值类型是将数据和内存保存在同一位置的类型。引用类型有一个指向内存位置的指针。

下面是一个具有名称为i的简单整数数据类型,其值被分配给另一个具有名称j的整数数据类型。这两个内存值都分配在栈上。

当我们将int值分配给另一个int值时,它会创建一个完全不同的副本。换句话说,如果你改变其中一个,另一个不会改变。这些类型的数据类型称为“值类型”。

当我们创建一个对象并将一个对象分配给另一个对象时,它们都指向相同的内存位置,如下面的代码片段所示。所以当我们赋值obj给obj1时,它们都指向同一个内存位置。

换句话说,如果我们改变其中一个,另一个对象也会受到影响;这被称为“引用类型”。

那么哪些数据类型是引用类型,哪些是值类型?

在.NET中,根据数据类型,变量要么在栈上分配,要么在堆上分配。'String'和'Objects'是引用类型,任何其他.NET原始数据类型都在栈上分配。下图以更详细的方式解释了相同的内容。

装箱和拆箱

哇,你传授了这么多知识,那么在实际编程中又有什么用呢?最大的影响之一是了解由于数据从栈移动到堆(反之亦然)而导致的性能损失。

考虑下面的代码片段。当我们将值类型移动到引用类型时,数据从栈移动到堆。当我们将引用类型移动到值类型时,数据从堆移动到栈。

这种从堆到栈的数据移动,反之亦然,这会导致性能下降。

当数据从值类型移动到引用类型时,它被称为“装箱”,反之则被称为“拆箱”。

如果您编译上述代码并在ILDASM中看到相同的内容,您可以在IL代码中看到“装箱”和“拆箱”的样子。下图演示了相同的内容:

装箱和拆箱的性能含义

为了查看性能如何受到影响,我们运行了以下两个函数10,000次。一个函数有装箱,另一个函数很简单。我们使用秒表对象来监控所用的时间。

装箱函数在3542毫秒内执行,而没有装箱时,代码在2477毫秒内执行。换句话说,尽量避免装箱和拆箱。在需要装箱和拆箱的项目中,在绝对必要时使用它。

本文附带了示例代码,演示了这种性能影响。

目前,我还没有包括拆箱的源代码,但同样适用于它。您可以使用stopwatch类编写代码并对其进行试验。

关于源代码

随文章附有一个简单的代码,它演示了装箱如何产生性能影响。您可以在此处下载源代码。

Six Important .NET Concepts: Stack, Heap, Value Types, Reference Types, Boxing, and Unboxing - CodeProject

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

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

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

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

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

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

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

  4. 装箱与拆箱的概念及意义

    1.   装箱和拆箱是一个抽象的概念 2.   装箱是将值类型转换为引用类型 :拆箱是将引用类型转换为值类型     利用装箱和拆箱功能,可通过允许值类型的任何值与Object 类型的值相互转换,将值 ...

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

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

  6. C#核心概念--装箱和拆箱(什么是装箱和拆箱)

    装箱(boxing)和拆箱(unboxing)是C#类型系统的核心概念.是不同于C与C++的新概念!,通过装箱和拆箱操作,能够在值类型和引用类型中架起一做桥梁.换言之,可以轻松的实现值类型与引用类型的 ...

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

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

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

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

  9. 理解C#中装箱和拆箱的概念

    前言 C#数据类型 什么是装箱.拆箱 产生装箱.拆箱的举例 总结 前言 C# 是一种通用.面向对象的编程语言,由微软(Microsoft)开发的,属于强类型语言,变量需先声明数据类型.然后给变量赋初值 ...

最新文章

  1. 啥不懂也能动手搭建属于自己的博客网站
  2. PHP的postman请求的五种数据样式
  3. eclipse+webservice开发实例
  4. Arm Linux交叉编译和连接过程分析(2)
  5. XM7 FOR ANDROID,如何使用Android Studio开发Gradle插件
  6. 从0到1开发自动化测试框架(硬货太多,建议阅读)
  7. java string对象,java中String对象
  8. 温湿度压力传感器——BME280,硬件开发与程序设计
  9. thymeleaf渲染搜索页面(template: “class path resource [templates/serach.html]“)-serach2021-09-23
  10. 隧道点云处理(三):一种简单的隧道二维中线提取方法
  11. 微美全息正式成立“全息元宇宙事业部”;孩之宝旗下威世智发布一系列万智牌产品;区块链专家赵亮正式加盟宏桥高科 | 全球TMT...
  12. 网易2019实习生招聘算法题(一)
  13. 长盛兴业入股宝沃背后:为神州优车相关方 王百因是陆正耀同学
  14. 如何快速将显示未签收的单号物流归类为签收件
  15. DVWA靶场系列1-环境搭建
  16. 2022年最新云开发去水印小程序源码
  17. 厘米换算英尺英寸 (15 分)
  18. 一期项目实战:问卷调查—人事管理系统
  19. windbg调试minidump
  20. SAP/PP-40策略下SO不消耗PIR问题

热门文章

  1. python全栈和java全栈_全栈和python的区别
  2. 电脑软件怎么卸载干净_软件分享(一)【电脑】软件卸载工具
  3. linux ntfs 用户权限,linux权限及ntfs文件系统权限的知识
  4. 加载geojson面数据_地理数据可视化
  5. plsql如何显示表结构图_产品经理需了解的架构图/结构图知识
  6. PNG免扣(抠)素材,直接应用才是设计师友好的帮助图片
  7. 字体设计灵感合集|字体决定了设计
  8. 圣诞节美食聚会派对海报设计
  9. 设计素材模板|如何从优秀作品里学习版面设计?
  10. 干货 · UI设计|APP引导页面可临摹素材