(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 ...
随机推荐
- 步步入佳境---UI入门(2)
一,刚开始练习UI的时候,一般是在- (void)viewDidLoad方法中写代码测试,例如:- (void)viewDidLoad{ CGRect rect=CGRectMake(0, 0, ...
- 神经网络损失函数中的正则化项L1和L2
神经网络中损失函数后一般会加一个额外的正则项L1或L2,也成为L1范数和L2范数.正则项可以看做是损失函数的惩罚项,用来对损失函数中的系数做一些限制. 正则化描述: L1正则化是指权值向量w中各个元素 ...
- pip source
linux版本 sudo vim .pip/pip.conf[global]index-url = http://pypi.douban.com/simple[install]trusted-host ...
- c++ 与 java 中的 继承
C++ 代码: #include <iostream> #include <string> using namespace std; class Parent { public ...
- 游标 cursor
* mongo shell下支持JS代码,可以通过JS获取游标,进而获取数据操作结果. var cursor = db.class1.find() cursor.next() 获取下一条结果 curs ...
- leetcode:Pascal's Triangle II【Python版】
1.将tri初始化为[1],当rowIndex=0时,return的结果是:1,而题目要求应该是:[1],故将tri初始化为[[1]],返回结果设置为tri[0]即可满足要求: 2.最开始第二层循环是 ...
- .NET4.0框架退休日期逐渐临近
微软宣布了.NET框架4.0至4.5.1版本的生命周期终结计划. 2016年1月12日之后,所有的技术支持,包含安全和非安全的更新补丁,都将会停止.开发人员和用户到时候可以选择回退到.NET 3.5 ...
- 使用 dl 设计的简单的登陆界面 (为了记录)
先贴图 对应的地方放置 一些登陆的图片即可 html 代码如下: <html><head><style>body {text-align:center;margin ...
- 转 oracle 学习- 用户权限角色
创建和删除用户是Oracle用户管理中的常见操作,但这其中隐含了Oracle数据库系统的系统权限与对象权限方面的知识.掌握还Oracle用户的授权操作和原理,可以有效提升我们的工作效率. Oracle ...
- 实战:mysql检查物理磁盘中的二进制日志文件是否有丢失
版权声明:日常札记,乐于分享 https://blog.csdn.net/yangzhawen/article/details/32103555 场景:有时候由于磁盘损坏或人为原因错误删除了磁盘中的二 ...