(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 ...
随机推荐
- 大龄码农那些事——也谈996.ICU
1.背景 近期Github突然有一个开源项目火了,叫“996.icu”,开源地址:https://github.com/996icu/996.ICU ,目前star的人数截止我写这篇博文时已经高达17 ...
- shell 脚本实战笔记(5)--搭建资源的镜像服务器
背景: 由于访问国外站点资源, 有时特别慢. 偶尔一次下载, 肯定还能忍受, 对于多次使用或者小团队内部使用, 搭建一个镜像站点, 无疑是个明智的决定. 这边以搭建CDH5的yum源镜像, 作为例子, ...
- requests.exceptions.MissingSchema
requests.exceptions.MissingSchema: Invalid URL '//p9.pstatp.com/list/pgc-image/1538380201743a84869e0 ...
- PDB调试模块
这里主要是一些对于调试常用的命令:1.直接通过命令端输入进行调试 以pdb调试模式运行(主要用这个) python3 -m pdb file.py 2.在代码中导入pdb模块 import pdb 功 ...
- C#浮点数保留位数
C#浮点数保留位数 这里用String.Forma("{0:F}",x);来解决. 下面是试验和截图 using System; using System.Collections. ...
- 各种CTF的WP
http://l-team.org/archives/43.html PlaidCTF-2014-twenty/mtpox/doge_stege-Writeup http://l-team.org/a ...
- 【liunx】端口号的占用情况查看
Linux如何查看端口 1.lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000 # lsof -i:8000 COMMAND PID USER ...
- LG1600 天天爱跑步
题意 分析 对一个(s,t)查询,令f=lca(s,t),则操作可化为(s,f),(f,t). 考虑观察到的情况,若x在s到t的路径上,且x观察到,则 \[ \textrm{dep}_s-\textr ...
- UVA10590 Boxes of Chocolates Again
题意 将正整数N拆分成若干个正整数之和,问有多少种不重复的拆分方案. \(n \leq 5000\) 分析 用f(i,j)表示将i拆成若干个数字,最大的那个数字(即最后一个数)不超过j的方案数. 转移 ...
- JavaWeb学习总结(二)-修改Tomcat服务器的端口(半年之后再总结)
一.Tomcat服务器端口的配置 Tomcat的所有配置都放在conf文件夹之中,里面的server.xml文件是配置的核心文件(hibernate.cfg.xml是核心配置文件). 如果想修改Tom ...