(c#) 销毁资源和释放内存
0. 什么是资源? .NET 框架中如何访问资源?
所谓的资源就是程序中可利用的数据,譬如:字符串、图片和任何二进制数据,包括任何类型的文件。
在面向对象的环境中,每一个类型都标识为某些程序所用的资源,要想使用这些资源,必须为相应的类型分配一定的内存空间。
访问一个资源需要如下几个步骤:
1)分配内存空间: 调用中间语言(IL)中的newobj指令(使用new操作符时,将产生newobj指令),为某个特定资源的类型分配一定的内存空间。
2) 初始化内存: 一个类型的实例构造器负责这样的初始化工作。
3)使用资源: 通过访问类型成员来使用资源。根据需要会有反复。
4)销毁资源: 执行清理工作。
5)释放内存: 托管堆上的内存由GC全权负责, 值引用的在栈上的内存会随着栈空间的消亡而自动消失。
1. 什么是托管资源,非托管资源?
托管资源是由CLR全权负责的资源,CLR不负责的资源位非托管资源。
对于托管资源通过GC自动回收。
对于非托管资源GC管理,通过代码调用手动进行清除。
2. 什么是垃圾, 什么是垃圾回收?
Net类型分为两大类,一个就是值类型,另一个就是引用类型。前者是分配在栈上,并不需要GC回收;后者是分配在堆上,因此它的内存释放和回收需要通过GC来完成,
那么只有被称为垃圾的对象才能被GC回收。也就是说,一个引用类型对象所占用的内存需要被GC回收,需要先成为垃圾。
那么.Net如何判定一个引用类型对象是垃圾呢,.Net的判断很简单,只要判定此对象或者其包含的子对象没有任何引用是有效的,那么系统就认为它是垃圾。
内存的释放和回收需要伴随着程序的运行,因此系统为GC安排了独立的线程。那么GC的工作大致是,查询内存中对象是否成为垃圾,然后对垃圾进行释放和回收。
那么对于GC对于内存回收采取了一定的优先算法进行轮循回收内存资源。
其次,对于内存中的垃圾分为两种,一种是需要调用对象的析构函数,另一种是不需要调用的。
GC对于前者的回收需要通过两步完成,第一步是调用对象的析构函数,第二步是回收内存,但是要注意这两步不是在GC一次轮循完成,即需要两次轮循;相对于后者,则只是回收内存。
3. 如何正确的释放资源?
托管的内存资源,这是不需要我们操心的,系统已经为我们进行管理了。
对于非托管的资源,这里再重申一下,就是Stream,数据库的连接,GDI+的相关对象,还有Com对象等等这些操作系统资源,需要我们手动去释放。
如何去释放,应该把这些操作放到哪里比较好呢。.Net提供了三种方法,也是最常见的三种,大致如下:
1. 析构函数;
2. 继承IDisposable接口,实现Dispose方法;
3. 提供Close方法。
|
析构函数 |
Dispose方法 |
Close方法 |
|
|
意义 |
销毁对象 |
销毁对象 |
关闭对象资源 |
|
调用方式 |
不能被显示调用,会被GC调用 |
需要显示调用 或者通过using语句 |
需要显示调用 |
|
调用时机 |
不确定 |
确定,在显示调用或者离开using程序块 |
确定,在显示调用时
|
(c#) 销毁资源和释放内存的更多相关文章
- PHP unset销毁变量并释放内存
PHP的unset()函数用来清除.销毁变量,不用的变量,我们可以用unset()将它销毁.但是某些时候,用unset()却无法达到销毁变量占用的内存!我们先看一个例子: <?php $s=st ...
- PHP如何释放内存之unset销毁变量并释放内存详解
PHP的unset()函数用来清除.销毁变量,不用的变量,我们可以用unset()将它销毁.但是某些时候,用unset()却无法达到销毁变量占用的内存!我们先看一个例子: <?php $s = ...
- PHP unset()函数销毁变量 但没有实现释放内存
<?PHP $a = "hello";$b = &$a;unset( $b );echo $a; // 输出 helloecho $b; // 报错$b = &quo ...
- redis资源未释放引发的问题
一.redis资源未释放的起因: N年前,在修改一个古老程序时,不小心把redis释放的这块给干掉了, if (jedis != null) { if (!isInProcess) { jedis.d ...
- android回收AnimationDrawable动画的每一帧的图片资源,而释放内存
回收每一帧的图片,释放内存资源 private void tryRecycleAnimationDrawable(AnimationDrawable animationDrawables) { if ...
- 转 cocos2d-x 优化(纹理渲染优化、资源缓存、内存优化)
概述 包括以下5种优化:引擎底层优化.纹理优化.渲染优化.资源缓存.内存优化 引擎优化 2.0版本比1.0版本在算法上有所优化,效率更高.2.0版本使用OpenGl ES 2.0图形库,1.0版本 ...
- Delphi动态创建组件,并释放内存
开发所用delphi版本是xe2,效果图如下: 代码如下: ---------------------------------------------------------------------- ...
- Linux释放内存
在Linux系统下,我们一般不需要去释放内存,因为系统已经将内存管理的很好.但是凡事也有例外,有的时候内存会被缓存占用掉,导致系统使用SWAP空间影响性能,此时就需要执行释放内存(清理缓存)的操作了. ...
- 如何为linux释放内存和缓存
如何为linux释放内存和缓存_华陌飞尘_新浪博客 如何为linux释放内存和缓存 (2011-10-20 10:49:01) 标签: linux swap me ...
随机推荐
- 玩转TypeScript(引言&文章目录) --初看TypeScript.
JavaScript过去一直被当作一种玩具语言存在,直到2005年以后,这门语言又开始活跃并可以说是火爆,而且随着浏览器版本的不断升级和完善,各种DOM之间的兼容性已经渐渐的被各种技术解决了,比如经典 ...
- [LeetCode&Python] Problem 496. Next Greater Element I
You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...
- [Algorithm] A nonrecursive algorithm for enumerating all permutations of the numbers {1,2,...,n}
def permutationN(n): a=[None]*n for i in range(n): a[i]=i+1 sum=1 for j in range(n): sum*=(j+1) i=0 ...
- 五个对你有用的Everything搜索技巧
分享五个对你有用的Everything搜索技巧: 一, empty:(查找空文件夹);二, dupe:(查重复文档);三, 空格(与), |(或),!(非); 四, e:\ (路径搜索);五, wil ...
- php curl批处理
php模拟多线程用到curl库,这个库很强大,可以做好多事,比如模拟登陆,文件上传/下载,数据采集等. 下面是我的代码,很简单,有些还功能还不会用. <?php $node_urls=array ...
- Typescript(ES6) ...用法
简单例子: //数组深拷贝 var arr2 = arr; var arr3 = [...arr]; console.log(arr===arr2); //true, 说明arr和arr2指向同一个数 ...
- MVC的好处 演示
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- Java 中的语法糖(7/15整个周六上午总结)
语法糖定义指的是,在计算机语言中添加某种语法,这种语法能使程序员更方便的使用语言开发程序,同时增强程序代码的可读性,避免出错的机会:但是这种语法对语言的功能并没有影响.Java中的泛型,变长参数,自动 ...
- adb学习笔记
一.adb实现原理 adb的目的是想仅在PC端执行adb操作来获取手机里面的文件或向手机内部发送文件.这是通过Ubuntu中adb操作作为客户端与Ubuntu中运行的adb service交互,Ubu ...
- alpha和color key
一.alpha 1.透明度,一般取值0-255 2.Alpha 通道: Alpha 通道是为保存选择区域而专门设计的通道.在生成一个图像文件时,并不必须产生 Alpha 通道.通常它是由人们在图 ...