C#托管和非托管资源

C#托管和非托管资源

一、基础概念

  1. 内存:程序运行于内存上,存储变量,函数,对象等数据,暂时存储CPU运算数据,
  2. 虚拟内存:
  3. 堆:也称托管堆,用于存储对象的数据结构,CPU无法直接读取
  4. 栈:用于存储变量的数据结构,CPU能直接读取
  5. 变量的生命周期:创建->使用->释放(该变量不在被使用,超过定义域范围)
  6. 对象的生命周期:
  7. 垃圾回收器:垃圾回收器运行时,会自动清理堆中不再引用的所有对象;通过调用System.GC.Collect()方法来强制执行垃圾回收,该方法常用于代码中有大量的对象刚取消引用时
  8. 托管资源:存放在堆上的对象,可由垃圾回收器回收
  9. 非托管资源:文件句柄、网络连接和数据库连接等成为非托管资源;

二、如何释放非托管资源

  1. 析构函数(终结器):频繁使用析构函数会影响性能
protected override void Finalize()
{
    try
    {
        // Finalizer implementation
    }
    finally
    {
        base.Finalize();
    }
}
  1. 继承IDisposable接口:该接口有一个Dispose()方法,Dispose()可以显式的释放对象所使用的非托管资源;如果在释放资源的过程中出现异常可以使用theInstance?.Dispose();来释放资源
ResourceGobbler theInstance = null;
try
{
    theInstance = new ResourceGobbler();
    // do your processing
}
finally
{
    theInstance?.Dispose();
}
  1. using关键字:自动实现IDisposable接口,超过作用域自动调用Dispose()方法,且出现异常也会调用Dispose()方法
using (var theInstance = new ResourceGobbler())
{
	// do your processing
}
  1. 析构函数与IDisposable接口双重组合
public class ResourceHolder : IDisposable
{
    private bool _isDisposed = false;
    public void Dispose()
    {
        Dispose(true);
        //告诉垃圾回收器不要调用指定对象的Dispose方法,因为之前Dispose(true);已经做过了。防止两次执行。
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                // Cleanup managed objects by calling their
                // Dispose() methods.
            }
            // Cleanup unmanaged objects
        }
        _isDisposed = true;
    }
    ~ResourceHolder()
    {
        Dispose(false);
    }
    public void SomeMethod()
    {
        // Ensure object not already disposed before execution of any method
        if (_isDisposed)
        {
            throw new ObjectDisposedException("ResourceHolder");
        }
        // method implementation…
    }
}

四、不安全代码

  1. 指针:
    1)优点:提高性能
    2)缺点:编码和调试较为困难,无法通过CLR施加的内存类型安全检查
  2. unsafe关键字:用于编写不安全代码,为了保持类型安全,默认情况下,C# 不支持指针算法,因此C#只允许在特别标记的代码块中使用指针。

unsafe 在C# 程序中的使用场合:
1)实时应用,采用指针来提高性能;
2)引用非.net DLL提供的如C++编写的外部函数,需要指针来传递该函数;
3)调试,用以检测程序在运行过程中的内存使用状况。

使用unsafe 的利弊:
好处:性能和灵活性提高;可以调用其他dll的函数,提高了兼容性;可以得到内存地址;
坏处:非法修改了某些变量;内存泄漏。

unsafe 与unmanaged的区别:
managed code是在CLR监管下运行的程序。以下任务由CLR来执行:管理对象内存,类型安全检测和冗余处理。
unmanaged code也就是能由程序员直接进行内存操作的程序。
unsafe 是介于managed和unmanaged之间的桥梁,它使得managed code也能使用指针来控制和操作内存。

/*
表示假设所有的成员都是不安全的
*/
public unsafe class MyClass
{
	// any method in this class can now use pointers
}

unsafe int GetSomeNumber()
{
    // code that can use pointers
}

unsafe
{

}

unsafe int* pX;//pX必须为成员变量,不能把局部变量本身标记为unsafe

在这里插入图片描述
注:解决“不安全代码只会在使用 /unsafe 编译的情况下出现”方法,修改程序集属性。如上图所示
3.

参考链接:
C#学习之unsafe

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值