非常久不写博客了,不是由于不想写,仅仅是近期公司任务比較多,最终十一有时间出来冒泡了。

今天继续介绍移动开发中的重中之重——内存管理。
C#代码是托管代码,C# 程序猿非常少像C/CPP程序猿那样为程序资源的释放而头疼,一个C/CPP高手必须是内存管理的高手,作为C#程序尽管不要求像C/CPP程序猿那样管理内存资源,可是对内存机制还须要有深入的理解,那些代码资源是托管资源交给GC去处理,那些资源须要程序猿手工释放,当然大家更关心的是非托管资源,由于托管资源GC会自己主动清理。

一般查看一个类是否是托管资源通常能够这样做,在VS里F12转到定义,查看类或父类是否实现了IDisposable接口,全部实现了IDisposable接口的类都须要手动释放资源,GC是不会清理这些资源的,在C#中实现了IDisposable接口常见的类有:数据库连接父类DbConnection以及各种数据库Adapter,Command等类,各种文件流父类Stream等类。

对于这些类,我们有两种策略。
策略一:
      在我们使用这些类的时候都用try...catch...finally语句,在finally里面进行释放资源。详细做法例如以下:
public class SqlHelper
{
//获取配置文件里的数据库连接字符串
private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; /// <summary>
/// 支持存储过程的通用返回DataTable的数据库參数查询方法
/// </summary>
/// <param name="sqlstr">查询SQL字符串</param>
/// <param name="cmdtype">命令类型</param>
/// <param name="paras">參数</param>
/// <returns>DataTable结果集</returns>
public static DataTable ExecuteDataTable(string sqlstr, CommandType cmdtype, params SqlParameter[] paras)
{
//创建实现IDisposable接口类对象
SqlDataAdapter adapter = null;
try
{
adapter = new SqlDataAdapter(sqlstr, ConnStr);
DataTable dt = new DataTable();
adapter.SelectCommand.CommandType = cmdtype;
if (paras != null && paras.Length > 0)
{
adapter.SelectCommand.Parameters.AddRange(paras);
}
adapter.Fill(dt);//运行到此,adapter已经用完
return dt;
}
catch(Exception e)
{
//记录错误日志等操作
return null;
}
finally
{
//释放非托管资源
adapter.Dispose();
}
}

这样,当我们在调用SqlHelper的ExecuteDataTable方法的时候,我们就不必在关心Adapter对象资源的释放,finally语句会在我们用完Adapter的时候自己主动将资源释放,这样尽管满足了我们的要求,可是这样似乎有点麻烦,好的。
策略二:
  那就用C#的using语句,详细例如以下:
       
 public static DataTable ExecuteDataTable(string sqlstr, CommandType cmdtype, params SqlParameter[] paras)
{
//实现了IDisposable接口的类对象
using (SqlDataAdapter adapter = new SqlDataAdapter(sqlstr, ConnStr))
{
DataTable dt = new DataTable();
adapter.SelectCommand.CommandType = cmdtype;
if (paras != null && paras.Length > 0)
{
adapter.SelectCommand.Parameters.AddRange(paras);
}
adapter.Fill(dt);
return dt;
}
}


这样写比用try..finally方便了很多,仅仅要using实现IDisposable接口的对象,using语句块走完IDisposable对象会被自己主动释放,注意,没有实现IDispoable接口的类是不能被using的,事实上using内部也是try...catch...finally的实现,仅仅是微软给封装好了,这也是C#程序猿专有的语法糖。

当然,假设你也想实现IDisposable接口,可以被using,那么你就參考微软MSDN建议的演示样例就行了,我在这里就不多墨迹了。

       说完非托管对象,该说托管对象,托管对象全然交由CLR的GC统一管理,那么什么时候GC会回收一下托管资源呢?

所谓托管资源,没有实现IDisposable接口的一般类,没有文件和数据库操作等,比如,int,string,List等,当我们在使用这些对象时,我们不须要关心他们的释放,他们会由GC统一处理,一般假设系统内存够用GC就不会回收这些托管资源,当内存紧张时GC会回收那些没有不论什么引用指向的对象,当然C#也给程序猿提供了手动调用GC回收的方法,GC.Collect()方法,可是即使程序猿即使手动调用了该方法,GC也不一定在那一时刻对托管资源进行回收,另外Collect()方法不建议程序猿手动的调用,假设频繁调用会严重拖垮程序的性能,由于内存频繁的回收,C#有三级垃圾回收,想了解的能够百度一下。

在站点的开发中,往往愿意牺牲适当的内存来提高站点的性能,由于内存的存取速度远远超过磁盘的速度,这样会缓解站点大并发带来的压力,因此也产生了一批Memcached、Redis等server内存管理软件,甚至MySql数据库也能够把数据存储在内存中,当然server重新启动内存数据一般就无法恢复了(Redis能够恢复),因此应该把什么数据放到内存中是开发的关键。

       做为移动开发者,对于内存的管理更是很重要的。由于我们不像站点server有那么大的内存,眼下来看,我听说的内存最大的莫过于微软的Surface Pro3,这是平板电脑的配置,可是假设是手机呢?最大的应该是小米的第4代手机3G内存,然后眼下主流手机的内存应该在1.5G左右,苹果的手机内存要更小,面对这么小的内存,程序猿开发时就一定要把握内存的使用。

既然手机内存那么小,是不是我把全部的资源使用后就立刻释放就好呢?这样最节省资源啊?事实上不是,这要依据详细的需求来定,有些情况下我们能够把一些经常使用的资源临时放在内存中,等再次使用时从内存中调用能够大大提高程序的调用的速度,这里我们能够借助Framework的线程池原理,假设线程池里有线程对象,就用线程池里的对象,没有再开启一个新的线程。

这里必需要说的一个重要的知识点即使弱引用,WeakReference类的原理是,将对象用WeakReference指向,然后将那个对象是置为null(被GC发现能够及时回收),我们在使用的时候直接使用WeakReference对象指向的对象就能够了,WeakReference会自己主动管理对象,当内存中有需要的对象,就直接使用,没有就在内存中创建一个,详细用法例如以下:
 
object obj = new object();
//对象由弱引用指向
WeakReference wref = new WeakReference( obj );
//将对象置为null
obj = null;
//使用弱引用指向的对象
object currObj=wref.Target;
//使用currObj完毕业务

       关于弱引用就简单的介绍到这里,当然弱引用的使用也不只不过这些,还有非常多,大家能够自己搜索一下,我就不过多介绍了,在后来的Windows Store应用开发里我会详细的举出弱引用的详细应用场景。假设想深入理解内存的使用,建议去网上看吕建中的设计模式视频中的享元模式,享元模式讲的是内存的共享,事实上开发中非常多东西都能够共享,深入理解池的概念非常重要。

好了,今天就到这里,我们下期见。

Windows移动开发(四)——闭关修炼的更多相关文章

  1. Windows移动开发(二)——闭关修炼

    一些武侠小说里的大人物,为了争夺武林盟主,号召天下,常常闭关修炼一段时间,闭关期间仅仅能接触送饭的人,而且关外还有非常多守卫的人员.还有,不管是篮球还是足球运动员,他们在真正接触球之前,都必须做非常长 ...

  2. Windows驱动程序开发基础(四)驱动的编译调试和安装

    Windows驱动程序开发基础,转载标明出处:http://blog.csdn.net/ikerpeng/article/details/38793995 以下说一下开发出来驱动程序以后怎样编译.一般 ...

  3. windows原生开发之界面疑云

        windows桌面开发,界面始终是最大的困惑.我们对前端工具的要求,其实只有窗体设计器.消息映射,过分点的话自适应屏幕.模型绑定.能够免于手工书写,其实这个问题并不复杂,但VS不实现.QT语法 ...

  4. Windows驱动开发(中间层)

    Windows驱动开发 一.前言 依据<Windows内核安全与驱动开发>及MSDN等网络质料进行学习开发. 二.初步环境 1.下载安装WDK7.1.0(WinDDK\7600.16385 ...

  5. Windows Phone开发-开发环境和结构

    Windows Phone 7.1的开发工具发布了,一直对WP7很关注,现在终于可以开始学习了.其实09年就学习过silverlight,看过3的SDK文档,当时因为工作,断断续续也没有坚持下来,所以 ...

  6. Kinect for Windows SDK开发入门(一):开发环境配置

    [译]Kinect for Windows SDK开发入门(一):开发环境配置 前几天无意中看到微软发布了Kinect for windows sensor,进去看了一下Kinect应用的例子,发现K ...

  7. Windows Phone开发人员必看资料

    win phone开发必看资料,下载地址收藏啦!收藏后可有选择性的下载,希望大家喜欢! 完整附件下载:http://down.51cto.com/data/414417 附件预览: Windows E ...

  8. Windows Phone开发(36):动画之DoubleAnimation

    原文:Windows Phone开发(36):动画之DoubleAnimation 从本节开始,我们将围绕一个有趣的话题展开讨论--动画. 看到动画一词,你一定想到Flash,毕竟WP应用的一个很重要 ...

  9. Windows Phone开发(33):路径之其它Geometry

    原文:Windows Phone开发(33):路径之其它Geometry 上一节中,我们把最复杂的PathGeometry给干了,生剩下几个家伙就好办事了.一起来见见他们的真面目吧. 一.LineGe ...

  10. Windows Phone开发(32):路径之PathGeometry

    原文:Windows Phone开发(32):路径之PathGeometry 说起路径这玩意儿,其实说的就是Path类,它藏在命名空间System.Windows.Shapes下,应该好找,它有一个很 ...

随机推荐

  1. 西门子PLC学习笔记七-(位逻辑指令)

    位逻辑指令处理的对象为二进制位信号.存储在状态字"RLO"中. 1.触点与线圈指令 1)常开触点 在PLC中规定:操作数为1,则常开触点"动作(闭合)":操作数 ...

  2. 数据结构读书笔记(三)(C语言)

    栈 顺序实现: 存储结构: #define STACK_INIT_SIZE 10 // 存储空间初始分配量 #define STACK_INCREMENT 2 // 存储空间分配增量 struct S ...

  3. JQuery 事件及案例

    JQuery事件与JavaScript事件相似,只是把其中的on去掉 1.click,dblclick事件 案例1:点击缩略图换背景 <html xmlns="http://www.w ...

  4. 【linux kernel】 softirq 软中断讨论

    欢迎转载,转载时需保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...

  5. _splitpath / _wsplitpath 将绝对路径分割为盘符、路径、文件名、扩展名。

    今天分享下一个路径分割的API,可以将一个完整的绝对路径分割为: 盘符(包括冒号:) 路径(包含前面&后面的\,不含盘符&文件名) 文件名(不含扩展名) 扩展名(包含前面的.) 先不说 ...

  6. delphi模态窗体最小化会隐藏的问题

    在使用delphi创建模态窗体的时候最小化窗体会导致最小化的窗体不可见,再次点击主窗体才会显示. 在这个模态窗体中增加以下函数 procedure WmSysCommand(var msg: TMes ...

  7. 仿Google首页搜索自动补全

    仿Google自动补全,实现细节: 后台是简单的servlet(其实就是负责后台处理数据交互的,没必要非跌用个struts...什么的) 传输介质:xml 使用jQuery js框架 功能实现: 如果 ...

  8. 透过表象看本质!?之三——Kalman滤波

    数据拟合能够估计出数据变化的趋势,另外一个同等重要的应用是如何利用这一趋势,预测下一时刻数据可能的值.通俗点儿说,你观察苍蝇(蚊子,蜜蜂)飞了几秒,你也许会想“它下一个时刻可能在哪儿”,“呈现出什么样 ...

  9. C/C++:多个.cpp文件包括同一个.h头文件定义方法

    本文解决multiple definition of `XX'的错误.[出于反爬虫的目的,你不是在http://blog.csdn.net/zhanh1218上看到的,肯定不是最新最全的.] 关于头文 ...

  10. freemarker自己定义标签报错(三)

    freemarker自己定义标签 1.错误描写叙述 freemarker.core.ParseException: Encountered " " at line 14, colu ...