c#

位置:IT落伍者 >> c# >> 浏览文章

c#基础学习之内存管理


发布日期:2022年12月26日
 
c#基础学习之内存管理

正式学习c#ASPNET已经有半年多了期间一直在忙一个项目很少有时间能够看看基础知识前两天看到一贴子突然发现自己的基础知识是如此的薄弱很多问题是知其然不知其所以然基础知识的缺失注定达不到你所想要的高度因此现在想抽出时间来看看基础但是自己有不想再去一页一页的看那本那么厚的《c#高级编程》和《ASPNET高级编程》所以想到什么地方就看什么地方了不求顺序但求效果

看了书后自己就想写点什么一是加深理解和印象二是和园友们共同探讨自己从来没有写过系列文章就从这里开始吧虽然都是写基础的东西对高手来说都是再简单不过了但对我这样的新手来说基础的才是最重要的

于是就写这个系列

内存管理

c#编程的一个优点是程序员不需要关心具体的内存管理尤其是垃圾收集器会处理所有的内存清理工作虽然不必手工管理内存但如果要编写高质量的代码还是要理解后台发生的事情理解c#的内存管理本文主要介绍给变量分配内存时计算机内存中发生的情况

c#将数据分为两种值数据类型和引用数据类型这两种数据类型存储在内存中的不同的地方值数据类型存储在堆栈中而引用类型存储在内存的托管堆中

内存简介

Windows使用一个系统虚拟寻址系统这个系统的作用是将程序可用的内存地址映射到硬件内存中的实际地址上其实际结果就是位的机子上每个进程都可以使用GB的内存当然位机这个数字就大了去了GB的内存实际上包含了程序的所有的部分可执行代码DLL以及程序运行时使用的所有变量的内容这个GB的内存成为虚拟地址空间或虚拟内存为方便这里成为内存

GB中的每个存储单元都是从零开始向上存储的要访问存储在内存中的某个空间中的值就必须提供表示该存储单元的一个数字在高级编程语言中编译器的一个重要作用就是负责将人们可以理解的变量名称变为处理器可以理解的内存地址

堆栈

在内存中有一个区域成为堆栈存储对象

对象成员的值数据类型调用方法时传递给所有方法的参数的副本注意调用方法时堆栈存储的是所有参数的副本因此经值类型A传递给函数A的值是不会变化的当然引用类型是会变化的因为在堆栈中存储的是引用类型的地址这在后面会有详细的介绍

下面以一个例子来说明堆栈的工作方式如下面的代码: {

: int a;

: //do something;

: {

: int b;

: //do something

: }

: }

首先声明a在内部的代码块中声明b然后内部的代码块终止b就出了作用域最后a出作用域所以b的生命周期总是包含在a的生命周期内在释放变量的时候其顺序总是和分配内存的顺序是相反的变量的生存周期都是嵌套的这就是堆栈的工作方式

托管堆

堆栈具有相当高的性能但是变量的生命周期必须是嵌套的这个要求在有的时候过于苛刻我们希望有一种别的方法来分配内存存储一些数据并在方法退出的很长一段时间内这些数据仍然是可用的这时就使用托管堆

托管堆(简称堆)是内存中的另外一个区域我们仍然用一个例子来说明堆的工作方式如下面代码: {

: Customer customer;

: customer=new Customer();

: Customer customer=new Customer();

: //do something

: }

首先声明一个Customercustomer在堆栈上给这个引用分配存储控件请注意仅仅是给这个引用分配存储空间并不是实际的Customer对象customer占用个字节的空间(位机)来表示Customer对象在内存中的地址

然后执行第二行代码完成以下操作

在堆上分配存储空间用来存储Customer对象注意这里是Customer对像

将变量customer的值设为分配给Customer对象的内存地址从这个例子中可以看出建立引用类型的变量的过程要比奖励值类型变量的过程复杂且不避免的有性能的降低但是我们可以将一个引用变量的值赋给另一个引用变量当一个变量出作用域时它会从堆栈中删除但是对象的数据仍然保留在内存中知道程序停止

这样我们在将一个引用变量A传递给函数时仅仅是将变量A的引用传递给了函数仅仅是在堆栈上分配内存即变量B两者指向同一个内存地址因此当变量B发生变化时变量A也会发生变化

装箱和拆箱

装箱和拆箱就是值类型和引用类型的项目转化装箱可以将值类型转化为引用类型拆箱的作用正好相反经引用类型转化为值类型

垃圾收集

一般情况下NET运行库会在认为需要的时候运行垃圾收集器来释放托管资源这在大多数情况下足够了就是说我们没有必要去关心内存但在有的情况下我们会强制垃圾回收集器在代码的某个地方运行释放内存这就用到了SystemGCCollect()SystemGC表示一个垃圾收集器这种情况很少例如代码中大量的对象刚刚停止引用就适合调用垃圾收集器

上一篇:浅谈.NET中不一样的多态

下一篇:C#实现文件管理器—by henryqin