当前位置:首页 > Windows程序 > 正文

【读书笔记】C#高级编程 第十四章 内存管理和指针

2024-03-31 Windows程序

(一)后台内存管理

1、值数据类型

Windows使用一个虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址,该任务由Windows在后台管理(32位每个进程可使用4GB虚拟内存,64位更多,这个内存包括可执行代码和加载的DLL,,以及程序运行时使用的变量内容)。

在处理器的虚拟内存中,有一个区域称为栈。栈存储不是对象成员的值数据类型。

释放变量时,其顺序总是与它们分配内存的顺序相反,这就是栈的工作方式。

程序第一次运行时,栈指针指向为栈保留的内存块末尾。栈实际上是向下填充的,即从高内存地址向低内存地址填充。当数据入栈后,栈指针就会随之调整,以始终指向下一个空闲单元。

 

2、引用数据类型

托管堆使用一个方法(new运算符)来分配内存,再方法退出后很长一段时间存储其中的数据仍可用。与栈不同,堆上的内存是向上分配的。

建立引用变量的过程要比建立值类型的过程更复杂,其不能避免性能的系统开销。当一个引用变量超出作用域时,它会从栈中删除,但引用的数据仍保留在堆中,一直到程序终止,会垃圾回收器删除它为止,而只有在改数据不再被任何变量引用时,它才会被删除。

 

3、垃圾回收器

垃圾回收器释放了能释放的所有对象,就会把其他对象移动回堆的端部,再次形成一个连续的块。

堆的第一部分称为第0代,创建的新对象会移动到这个部分。垃圾回收器每运行一次后保留的对象被压缩后移动到下一代存放部分。

在.NET下,较大对象有自己的堆,称为大象堆。使用大于85000个字节的对象时,它们就会放到这个特殊的堆上。

第二代和大象堆上的回收现在放在后台线程上进行。

GCSettings.LatencyMode属性可以控制垃圾回收器进行垃圾回收的方式。

 

(二)释放非托管资源

垃圾回收器不知道如何释放非托管资源(文件句柄、网络连接、数据库连接),需要制定专门的规则,确保非托管资源在回收类的一个实例时释放。

声明一个析构函数(或终结器),作为类的成员

实现IDisposable接口

 

1、析构函数

析构函数的语法,没有返回类型,不带参数,没有访问修饰符,与类同名前面有一个波形符(~)。

class MyClass { ~MyClass(){ //析构函数 } }

C#析构函数无法确定何时执行。C#析构函数的实现会延迟对象最终从内存中删除的时间。

 

2、IDisposable接口

C#中,推荐使用System.IDisposable接口替代析构函数。IDisposable接口声明了一个Disposable()方法,它不带参数,返回void。

class MyClass : IDisposable { public void Dispose() { //释放 } }

调用Dispose()方法:

MyClass my = new MyClass(); //代码 my.Dispose();

这种释放方式,如果在过程代码中抛出异常,Dispose()方法就没有被调用,导致内存没有被释放掉。

MyClass my = new MyClass(); try { //代码 } finally { my.Dispose(); }

通过以上调用方式,可以避免过程代码抛出异常,导致内存没被释放掉。还可以使用using关键字来简化调用,效果同上面一样。

using (MyClass my = new MyClass()) { //代码 }

 

 

(三)不安全代码

1、用指针直接访问内存

指针只是一个以与引用相同的方式存储地址的变量。

 

(1)用unsafe关键字编写不安全的代码

不安全代码所使用的关键字是unsafe。

unsafe class MyClass //不安全类 { unsafe public string Name { get; set; }//不安全属性 unsafe void SayHi()//不安全方法 { Console.WriteLine("Hi!"+ Name); } void SayBay() { unsafe int* pAge;//不安全局部变量需要在不安全方法里,这里会报错 Console.WriteLine("Bye!" + pAge); } }

 

(2)指针的语法

把代码块标记为unsafe后,使用以下语法声明指针:

int* age;

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/42923.html

Jm-杰米博客Jamie
草根站长的技术交流乐园!IT不会不要紧快来好好学习吧!
  • 20786文章总数
  • 7494595访问次数
  • 建站天数
  • 友情链接