C#内存管理之托管堆与非托管堆( reprint )
在 .NET Framework 中,内存中的资源(即所有二进制信息的集合)分为“托管资源”和“非托管资源”。托管资源必须接受 .NET Framework 的 CLR (通用语言运行时)的管理(诸如内存类型安全性检查),而非托管资源则不必接受 .NET Framework 的 CLR 管理。(了解更多区别请参阅 .NET Framework 或 C# 的高级编程资料)托管资源在 .NET Framework 中又分别存放在两种地方:“堆栈”和“托管堆”(以下简称“堆”);规则是,所有的值类型(包括引用和对象实例)和引用类型的引用都存放在“堆栈”中,而 所有引用所代表的对象实例都保存在堆中。在C#中,释放托管资源是可以自动通过“垃圾回收器”完成的(注意,“垃圾回收”机制是 .NET Framework 的特性,而不是 C# 的),但具体来说,仍有些需要注意的地方:1、值类型(包括引用和对象实例)和引用类型的引用其实是不需要什么“垃圾回收器”来释放内存的,因为当它们出 了作用域后会自动释放所占内存(因为它们都保存在“堆栈”中,学过数据结构可知这是一种先进后出的结构);2、只有引用类型的引用所指向的对象实例才保存 在“堆”中,而堆因为是一个自由存储空间,所以它并没有像“堆栈”那样有生存期(“堆栈”的元素弹出后就代表生存期结束,也就代表释放了内存),并且非常 要注意的是,“垃圾回收器”只对这块区域起作用;3、“垃圾回收器”也许并不像许多人想象的一样会立即执行(当堆中的资源需要释放时),而是在引用类型的 引用被删除和它在"堆"中的对象实例被删除中间有个间隔,为什么呢? 因为“垃圾回收器”的调用是比较消耗系统资源的,因此不可能经常被调用!(当然,用户代码可以用方法 System.GC.Collect() 来强制执行“垃圾回收器”)然而,大多数情况下,我们需要明确地在不执行“垃圾回收器”的情况下释放托管资源(因为只需要释放一部分但又是非常需要释放的 资源,但最好不要调用“垃圾回收器”,因为“垃圾回收器”太浪费系统资源了),或需要释放“非托管资源”,这时候我们该怎么办? 这是我们写代码的时候必须要考虑的问题(“垃圾回收器”是系统自动实现的,一般情况不需要用户干预),否则 Windows 系统会因为内存耗尽而……现在,我来告诉怎么办,那就是使用类的 Dispose() 方法释放所有类型资源和使用析构方法释放非托管资源!1、Dispose() 方法要通过Dispose()方法来释放资源,那么在类定义的时候执"System.IDisposable"接口,然后在类中必须包含这样定义的方 法"void Dispose()" (在Dispose()方法中就是用户自己写的释放资源的代码段),这样一来,用户就会知道可以通过人为地调用Dispose()方法来释放资源. 不过需要注意的是,"垃圾回收器"并不是通过调用Dispose()方法来释放托管资源的!2、析构方法在 C# 中定义析构方法的格式是“~CLASS_NAME()”。非常需要注意的是,如果一个类中没有使用到非托管资源,那么请一定不要定义析构方法,这是因为对 象执行了析构方法,那么“垃圾回收器”在释放托管资源之前要先调用析构方法,然后第二次才真正释放托管资源,这样一来,两次删除动作的花销比一次大多的! (不过,即使你在类中已经定义了析构方法,仍然有办法“屏蔽”它,这将在后面的代码范例中说明)在析构方法中,就是用户自己写的释放非托管资源的代码段。 下面使用一段代码来示范 Dispose() 方法和析构方法如何使用:
C#内存管理之托管堆与非托管堆( reprint )的更多相关文章
- C# 托管资源与非托管资源
在.net 编程环境中,系统的资源分为托管资源和非托管资源. 托管资源: Net平台中,CLR为程序员提供了一种很好的内存管理机制,使得程序员在编写代码时不要显式的去释放自己使用的内存资源(这些在先前 ...
- C# using 三种使用方式 C#中托管与非托管 C#托管资源和非托管资源区别
1.using指令.using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到. ...
- C# 托管资源 与 非托管资源
C# 托管资源 与 非托管资源 托管资源一般是指被CLR控制的内存资源,这些资源的管理可以由CLR来控制,.NET可以自动进行回收,主要是指托管堆上分配的内存资源.例如程序中分配的对象,作用域内的变量 ...
- 转/ C# 托管资源和非托管资源
原文 对于这两个一直就是模模糊糊的,半知零解 托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,由.NET运行库在合适时调用垃圾回收器 ...
- C# 托管资源和非托管资源
托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回 ...
- [转]在C#中使用托管资源和非托管资源的区别,以及怎样手动释放非托管资源:
托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回 ...
- .net 资源释放(托管资源和非托管资源)
1.托管资源 像int.float.DateTime等都是托管资源:net中80%的资源都是托管资源: 托管资源的回收通过GC(垃圾回收器)自动释放分配给该对象的内存,但无法预测进行垃圾回收的时间,我 ...
- 托管DLL和非托管DLL的区别
首先解释一下,托管DLL和非托管DLL的区别.狭义解释讲,托管DLL就在Dotnet环境生成的DLL文件.非托管DLL不是在Dotnet环 境生成的DLL文件. 托管DLL文件,可以在Dotnet环境 ...
- .net托管资源与非托管资源
在项目当中用到的资源分为托管资源和非托管资源,托管资源无非就是什么int.string.datatime之类,托管资源不需要人为去管理,.net framework中有专门针对托管资源的管理机制(GC ...
随机推荐
- 矩阵内积和Schur补
> Many problems in the field of signal processing have been expended into matrix problems.So it's ...
- Qt窗口屏幕居中显示
转自--> http://blog.chinaunix.net/uid-20718335-id-364404.html 窗口的屏幕居中显示问题,在各开发工具中原理相同,首先使用特定的方法得到显示 ...
- linux 软件包的命名规则
linux软件包的命名规则 eg:主包 bind-9.7.1-1.el7.i586.rpm 子包 bind-libs-9.7.1-1.el7.i586.rpm bind-utils-9. ...
- Web前端理论知识记录
Web前端理论知识记录 Elena· 5 个月前 cookies,sessionStorage和localStorage的区别? sessionStorage用于本地存储一个会话(session) ...
- php 设置页面导航动态active类样式的添加
在用php制作项目中,一般都是把页头和页脚分离出来.页头导航在选中状态时会有一些样式,例如active等,当页面在首页时候,导航的首页也应该是active的样式,那么,怎么用php控制这些样式的添加和 ...
- 【python】关于函数递归使用 return 后,收到数据为 None。
在写一个辗转相除求最小公因数的程序的时候,突然发现自己不管怎么写(除了两数恰巧可以整除),return 返回的值恒为 none. 代码为此: def gcd(a,b): if a%b==0: retu ...
- js事件绑定的几种方式与on()、bind()的区别
版权声明:本文为博主原创文章,未经博主允许不得转载 一直不是很理解几种js事件绑定之间的区别与联系,今天百度了一下,在此做一总结: 1.如果只是简单的绑定一个事件,可以直接写在行内,点击执行一个函数, ...
- BEC listen and translation exercise 38
很高兴看到有这么多人想了解我们的体育设施.It's good to see that there are so many people wanting to find out about our sp ...
- PS 滤镜——(扭曲)球面化 Spherize
%%%% Spherize clc; clear all; close all; addpath('E:\PhotoShop Algortihm\Image Processing\PS Algorit ...
- CI中site_url和base_url的区别
你若使用site_url("test/php/1");则实际url为 http://domain.com/index.php/test/php/1 若使用base_url(&quo ...