托管资源:通常是指被CLR(公共语言运行库)控制的内存资源,这些资源由CLR来管理。能够认为是.net 类库中的资源。数据库
非托管资源:不受CLR控制和管理的资源。数组
对于托管资源,GC负责垃圾回收。对于非托管资源,GC能够跟踪非托管资源的生存期,可是不知道如何释放它,这时候就要人工进行释放。安全
2. 后台内存管理服务器
介绍给变量分配内存时在计算机的内存中发生的状况网络
(1) 值数据类型:架构
(2) 引用数据类型:函数
void DoWork() { Customer arabel; // 在栈上给这个应用分配存储空间,但仅是一个引用,占用4个字节的空间,而不是实际的Customer对象。 arabel = new Customer(); // 首先分配堆上的内存,以存储Customer对象;再把变量arabel的值设置为分配给新Customer对象的内存地址。 // Customer实例没有放在栈中,而是放在堆中 // 与栈不一样,堆上的内存是向上分配的
//------------------------------------------------------------------ Customer otherCustomer2 = new EnhancedCustomer(); //用一行代码在栈上为otherCustomer2引用分配空间,同时在堆上为EnhancedCustomer对象分配空间。 }
(3) 垃圾回收性能
3. 强引用和弱引用优化
//建立一个DataObject,并传递构造函数返回的弱引用 var myWeakReference = new WeakReference(new DataObject()); if (myWeakReference.IsAlive) { DataObject strongReference = myWeakReference.Target as DataObject; if (strongReference != null) { //使用强引用对象 strongReference } } else { // 引用不可用 }
4. 处理非托管的资源ui
(1) 析构函数或终结器
(2) IDisposable接口:推荐使用,为释放非托管的资源提供了肯定的机制,精确控制什么时候释放资源。
SqlConnection conn = null; try { conn = new SqlConnection(); //do something; } finally { conn?.Dispose(); }
using(SqlConnection conn = new SqlConnection()) { //do something; }
(3) 双重实现:正确调用Dispose(),同时将析构函数做为一种安全机制。
public class BaseResource : IDisposable { private IntPtr _handle; // 句柄,属于非托管资源 private System.ComponentModel.Component _comp; // 组件,托管资源 private bool _isDisposed = false; // 是否已释放资源的标志 //实现接口方法 //由类的使用者,在外部显示调用,释放类资源 public void Dispose() { Dispose(true);// 释放托管和非托管资源 // 将对象从垃圾回收器链表中移除, // 从而在垃圾回收器工做时,只释放托管资源,而不执行此对象的析构函数 GC.SuppressFinalize(this); } //由垃圾回收器调用,释放非托管资源 ~BaseResource() { Dispose(false);// 释放非托管资源 } //参数为true表示释放全部资源,只能由使用者调用 //参数为false表示释放非托管资源,只能由垃圾回收器自动调用 //若是子类有本身的非托管资源,能够重载这个函数,添加本身的非托管资源的释放 //可是要记住,重载此函数必须保证调用基类的版本,以保证基类的资源正常释放 protected virtual void Dispose(bool disposing) { if (!this._isDisposed)// 若是资源未释放 这个判断主要用了防止对象被屡次释放 { if (disposing) { // 释放托管资源,调用其Dispose方法 _comp.Dispose(); } // 释放非托管资源 closeHandle(_handle); _handle= IntPtr.Zero; } this._isDisposed = true; // 标识此对象已释放 } }
5.不安全的代码:C#直接访问内存
(1) 用指针直接访问内存:
(2) 用unsafe关键字编写不安全的代码
void MyMethod() { // code that doesn't use pointers unsafe { // unsafe code that uses pointers here } // more 'safe' code that doesn't use pointers }
(3) 指针的语法
(4) 将指针强制转换为整数类型
(5) 指针类型之间的强制转换
(6) void指针
(7) 指针算术运算
(8)sizeof运算符:肯定各类数据类型的大小。
sizeof(char) = 2; sizeof(bool) = 1;
(9)结构指针:指针成员访问运算符
// 结构 struct MyStruct { public long X; public float F; } // 结构指针 MyStruct* pStruct; // 初始化 var myStruct = new MyStruct(); pStruct = &myStruct; // 经过指针访问结构的成员值 (*pStruct).X = 4; (*pStruct).F = 3.4f; // 使用成员访问运算符 pStruct->X = 4; pStruct->F = 3.4f; //指针指向结构中一个字段 long* pL = &(pStruct->X); float* pF = &(pStruct->F);
(10) 类成员指针
(11)使用指针优化性能:建立基于栈的数组。
int size; size = 20; double* pDoubles = stackalloc double[size];
6.平台调用
// C++ 调用Windows API(kernel32.dll)中CreateHardLink BOOL CreateHardLink( LPCTSTR lpFileName, LPCTSTR lpExistingFileName, LPSECURITY_ATTRIBUTES lpSecurityAttributes ); // C# 调用CreateHardLink [DllImport("kernel32.dll", SetLastError="true", EntryPoint="CreateHardLink", CharSet=CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CreateHardLink(string newFileName, string existingFilename, IntPtr securityAttributes);