c#基础(一)之内存管理
c#编程的一个优点是程序员不需要关心具体的内存管理,尤其是垃圾收集器会处理所有的内存清理工作。虽然不必手工管理内存,但如果要编写高质量的代码,还是要理解后台发生的事情,理解c#的内存管理。本文主要介绍给变量分配内存时计算机内存中发生的情况。
c#将数据分为两种:值数据类型和引用数据类型,这两种数据类型存储在内存中的不同的地方:值数据类型存储在堆栈中,而引用类型存储在内存的托管堆中。
一、内存简介
Windows使用一个系统:虚拟寻址系统。这个系统的作用是将程序可用的内存地址映射到硬件内存中的实际地址上。其实际结果就是32位的机子上每个进程都可以使用4GB的内存,当然,64位机这个数字就大了去了。这4GB的内存实际上包含了程序的所有的部分:可执行代码,DLL以及程序运行时使用的所有变量的内容。这个4GB的内存成为虚拟地址空间或虚拟内存。为方便,这里成为内存。
4GB中的每个存储单元都是从零开始向上存储的。要访问存储在内存中的某个空间中的值,就必须提供表示该存储单元的一个数字。在高级编程语言中,编译器的一个重要作用就是负责将人们可以理解的变量名称变为处理器可以理解的内存地址。
二、堆栈
在内存中,有一个区域成为堆栈,存储对象
- 对象成员的值数据类型
- 调用方法时,传递给所有方法的参数的副本
注意:调用方法时,堆栈存储的是所有参数的副本,因此,经值类型A传递给函数,A的值是不会变化的。当然,引用类型是会变化的,因为在堆栈中存储的是引用类型的地址,这在后面会有详细的介绍。
下面以一个例子来说明堆栈的工作方式,如下面的代码:
1: {
2: int a;
3: //do something;
4: {
5: int b;
6: //do something www.elivn.com
7: }
8: }
首先声明a,在内部的代码块中声明b。然后内部的代码块终止,b就出了作用域,最后a出作用域。所以b的生命周期总是包含在a的生命周期内,在释放变量的时候,其顺序总是和分配内存的顺序是相反的。即:变量的生存周期都是嵌套的。这就是堆栈的工作方式。
三、托管堆
堆栈具有相当高的性能,但是变量的生命周期必须是嵌套的,这个要求在有的时候过于苛刻。我们希望有一种别的方法来分配内存,存储一些数据,并在方法退出的很长一段时间内,这些数据仍然是可用的,这时,就使用托管堆。
托管堆(简称堆)是内存中的另外一个区域,我们仍然用一个例子来说明堆的工作方式,如下面代码:
1: {
2: Customer customer1;
3: customer1=new Customer();
4: Customer customer2=new Customer();
5: //do something
6: }
首先,声明一个Customer:customer1。在堆栈上给这个引用分配存储控件。请注意:仅仅是给这个引用分配存储空间,并不是实际的Customer对象。customer1占用4个字节的空间(32位机),来表示Customer对象在内存中的地址。
然后,执行第二行代码,完成以下操作:
- 在堆上分配存储空间,用来存储Customer对象,注意:这里是Customer对像。
- 将变量customer1的值设为分配给Customer对象的内存地址
从这个例子中可以看出,建立引用类型的变量的过程要比奖励值类型变量的过程复杂,且不避免的有性能的降低。但是,我们可以将一个引用变量的值赋给另一个引用变量,当一个变量出作用域时,它会从堆栈中删除,但是对象的数据仍然保留在内存中,知道程序停止。
这样,我们在将一个引用变量A传递给函数时,仅仅是将变量A的引用传递给了函数,即:仅仅是在堆栈上分配内存,即变量B。两者指向同一个内存地址。因此,当变量B发生变化时,变量A也会发生变化。
四、装箱和拆箱
装箱和拆箱就是值类型和引用类型的项目转化,装箱可以将值类型转化为引用类型,拆箱的作用正好相反,经引用类型转化为值类型。
五、垃圾收集
一般情况下,.NET运行库会在认为需要的时候运行垃圾收集器来释放托管资源,这在大多数情况下,足够了。就是说我们没有必要去关心内存。但在有的情况下,我们会强制垃圾回收集器在代码的某个地方运行,释放内存。这就用到了System.GC.Collect()。System.GC表示一个垃圾收集器。这种情况很少,例如:代码中大量的对象刚刚停止引用,就适合调用垃圾收集器。
六、总结
c#将内存分为两个区域:堆栈和堆。堆栈存放值类型,堆存放引用类型。.NET运行库会在认为需要的时候运行垃圾收集器来释放内存。
转载于:https://www.cnblogs.com/seoxs/archive/2011/04/25/2027176.html
c#基础(一)之内存管理相关推荐
- OC基础15:内存管理和自动引用计数
"OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.什么是ARC? (1).ARC全名为A ...
- 学了指针没学动态内存一切都白搭!C语言基础教程之内存管理
本文将讲解 C 中的动态内存管理.C 语言为内存的分配和管理提供了几个函数.这些函数可以在<stdlib.h>头文件中找到. 在内存中动态地分配 num 个长度为 size 的连续空间,并 ...
- MySQL 调优基础:Linux内存管理 Linux文件系统 Linux 磁盘IO Linux网络
http://www.cnblogs.com/digdeep/category/739915.html
- 《代码的未来》读书笔记:内存管理与GC那点事儿
一.内存是有限的 近年来,我们的电脑内存都有好几个GB,也许你的电脑是4G,他的电脑是8G,公司服务器内存是32G或者64G.但是,无论内存容量有多大,总归不是无限的.实际上,随着内存容量的增加,软件 ...
- flink分析使用之八内存管理机制
一.flink内存机制 在前面的槽机制上,提到了内存的共享,这篇文章就分析一下,在Flink中对内存的管理.在Flink中,内存被抽象出来,形成了一套自己的管理机制.Flink本身基本是以Java语言 ...
- c语言基础学习08_关于内存管理的复习
============================================================================= 对于c语言来讲,内存管理是一个很重要的内容, ...
- 【OC语法快览】四、基础内存管理
Basic Memory Management 基础内存管理 If you're w ...
- 操作系统内存管理_操作系统6内存管理基础
引言 花了一段时间才把之前的笔记整理了一部分,平时太忙也没啥时间.今天开始整理内存管理部分的,内存管理部分大致分为三部分笔记,第一部分就是本篇内存管理基础,第二部分是虚拟内存,第三部分高速缓存. 一个 ...
- java基础(一):谈谈java内存管理与垃圾回收机制
看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...
- 黑马程序员C语言基础(第七天)内存管理
黑马程序员C语言基础(第一天) 黑马程序员C语言基础(第二天) 黑马程序员C语言基础(第三天) 黑马程序员C语言基础(第四天)数据类型 黑马程序员C语言基础(第五天)运算符与表达式.程序流程结构.数组 ...
最新文章
- OSI第二层:数据链路层功能及作用
- 使用指针给矩阵除主对角线外的元素赋值为0
- 通过ID在JavaScript对象数组中查找对象
- python内置数据结构教程_python课程第二周 内置数据结构——列表和元组
- JAVA中获取当前运行的类名,方法名,行数
- mysql pt_mysql之pt工具之pt-fifo-split用法介绍
- 牛客网 [编程题]数字和为sum的方法数
- string类比较大小_源码阅读String--JAVA成长之路
- day18-事务与连接池 1.复习
- 换协议、改代码,Elastic要逼开发者二选一?
- 常用网线类别介绍(超五类、六类)
- 正则表达式-国际手机号或座机号校验
- switch 语句 -- 超详解
- qq服务器上的文件删除后如何恢复,qq文件过期怎么恢复(过期的QQ文件如何申请恢复)...
- 【应用统计学】方差分析
- 使用GitHub托管网站,自定义域名
- 泛微e-cology和Oracle无法启动的解决方案
- C++ Primer Plus习题及答案-第四章
- ssh 私钥公钥生成
- Qt中注册定义类型qRegisterMetaType和Q_DECLARE_METATYPE的总结
热门文章
- 试题14 回文数(详解)
- 牛客练习赛31: D. 神器大师泰兹瑞与威穆(链表)
- bzoj 3209: 花神的数论题 喵哈哈村的秘境探险(四)
- [Markdown] Markdown使用 - 持续更新
- [Python] np.ones_like(ndarray)和np.zeros_like(ndarray)
- jquery文本和值text、html、attr、val
- 十六进制的形式在屏幕中间显示二进制byte类型数据
- OpenGL加载2D的草地
- maven本地仓库中存在jar包,但编译不成功,显示jar包不存在
- 数据结构之线性表之顺序存储结构(3)