C#内存泄露与资源释放 经验总结
本文链接:http://blog.csdn.net/yokeqi/article/details/41083939
C#相比其他语言,拥有强大的垃圾回收机制,但并不是这样,你就可以对内存管理放任不管,其实在稍不注意的时候,可能就造成了内存泄露,甚至因此程序崩溃。
以下是遇到过的内存优化-内存泄露的问题与应对方案。
场景:
1. Form.ShowDialog()问题。
private void button1_Click(object sender, EventArgs e)
{
new Form2.ShowDialog();
}
如果你觉得写这样的一段代码很Cool,很简洁,你在项目也有这么写代码,那你就碰到大麻烦了,你试试在Form2中开个大一点的数组来检查内存,然后运行,按几下button1按钮,你就会发现,内存一直增加,即使你调用GC也无济于事。
2. 窗体向全局性事件注册了事件的问题。
public Form2()
{
InitializeComponent();
MyApp.FormChanged += FormChanged;
}
MyApp是一个静态类,如果向这种类里面注册了事件,而又没有取消注册,这样也会遇到大麻烦。即使在外部已经记得调用了Form2实例的Dispose也是没用的。
实际上由于各个开发人员的水平跟接触面不同,又没有经过统一的培训(各个人对内存释放的理解与关注度不同,或者写代码时就没考虑内存未被释放这种问题),发现问题的时候项目往往已经做到了一个阶段(SIT测试),系统也比较庞大了,这种时候才发现内存泄露的问题确实是很头疼的。
解决方案:
1. 基于架构师的经验,或者统一意见会议,在开发前对开发人员进行必要的统一培训,对关系到性能、内存等会影响系统稳定性的解决方案进行培训。这本身既有助于开发人员水平的提高,也对系统的稳定性方面提供很大的保障(项目可不是做完一个就没了,这种培训会带来长久的增益效果)。
2. 注意托管资源与非托管资源的释放区别,非托管资源是需要手动释放的。
3. 使用using关键字,避免忘记Dispose的情况,如上面的ShowDialog问题。(using中还起到了try-catch的作用,避免由于异常未调用Dispose的情况)
4. 使用UnLoad事件或者析构函数,对注册的全局事件进行取消注册。
5. 特别注意自定义组件的稳定性更重要,发生问题时影响也更广。注意继承IDisposable接口,进行资源释放,并且对有疑问/复杂逻辑的地方添加try-catch语句。(发现问题的人员不一定有权限修改这些组件)一定要保证组件健壮健壮,再健壮。这是我做组件的感悟~~~多么痛的领悟!!
最后特别奉送一个"内存释放"的大招:
调用这个API能让你的内存一下爆减:贴一段网上的示例代码
[DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);
/// <summary>
/// 释放内存
/// </summary>
public static void ClearMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
是不是很给力,一调用内存就降下来。先别高兴太早,这其实是伪释放,只为暂时解决内存大量泄露导致系统崩溃而急需解决的情况。
具体原因:http://blog.sina.com.cn/s/blog_49f8960e0100081x.html,关键字:将物理内存转到虚拟内存,涉及磁盘读写。
好处坏处都贴出来了,是否需要使用请君自己斟酌。
---------------------
作者:笨蛋的天赋
来源:CSDN
原文:https://blog.csdn.net/yokeqi/article/details/41083939
版权声明:本文为博主原创文章,转载请附上博文链接!
C#内存泄露与资源释放 经验总结的更多相关文章
- 【转】.. Android应用内存泄露分析、改善经验总结
原文网址:http://wetest.qq.com/lab/view/107.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.194 ...
- vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet
概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...
- 关于Android 的内存泄露及分析
一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...
- 关于Android 的内存泄露及分析(转)
一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...
- 基于HTML5的WebGL应用内存泄露分析
上篇(http://www.hightopo.com/blog/194.html)我们通过定制了CPU和内存展示界面,体验了HT for Web通过定义矢量实现图形绘制与业务数据的代码解耦及绑定联动, ...
- Valgrind检测内存泄露简介
原文地址: Valgrind 概述 体系结构 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核 ...
- C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针
C语言堆内存管理上出现的问题,内存泄露,野指针使用,非法释放指针 (1)开辟的内存没有释放,造成内存泄露 (2)野指针被使用或释放 (3)非法释放指针 (1)开辟的内存没有释放.造成内存泄露,以下的样 ...
- Flex内存泄露解决方法和内存释放优化原则
Flex内存泄露解决方法和内存释放优化原则 你对Flex内存泄露的概念是否了解,这里和大家分享一下Flex内存释放优化原则和Flex内存泄露解决方法,希望本文的介绍能让你有所收获. Flex内存释放优 ...
- JNI手动释放内存(避免内存泄露)
. 哪些需要手动释放? 不要手动释放(基本类型): jint , jlong , jchar 需要手动释放(引用类型,数组家族): jstring,jobject ,jobjectArray,jint ...
随机推荐
- WPF 精修篇 WPF 使用ActiveX
原文:WPF 精修篇 WPF 使用ActiveX WPF 实现远程桌面功能 首先使用 开发人员命令提示 进入 自己的项目文件根目录下 输入 aximp C:\windows\System32\msts ...
- digital clock based C
/********************************** * Name : timeDisplay.cpp * Purpose: Display digital clock accord ...
- 如何在git中上传图片
首先在git仓库上创建一个文件夹,之后点击 Upload files 上传本地的图片 上传完之后复制存放图片的git网址 之后在新建一个.md的子文件 新建完成之后在该md文件中写入如下代码: ![任 ...
- SpringBoot 打包成war
1.修改pom.xml文件 <packaging>war</packaging> <properties> <project.build.sourceEnco ...
- Javascript 日历插件
1. The Coolest Calendar 界面非常漂亮的一款日期选择插件,有详细的使用文档,最新版本 1.5. 点击下载 查看示例 2. DatePicker 这款日期插件支持单选.多选和 ...
- C#字符串(String)类型中@的用法
C# string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(\)当作普通字符对待,比如: string str = @"C:\Windows"; ...
- 基于vue+springboot+docker网站搭建【三】安装docker
安装docker 我们整个工程都会基于docker来跑,因此首先安装docker.在安装所有软件之前,我们需要先下载一个下载工具. 1.下载工具安装 yum-utils yum install -y ...
- Flask路由系统
Flask路由系统 我们之前了解了路由系统是由带参数的装饰器完成的. 路由本质:装饰器和闭包实现的. 设置路由的两种方式 第一种: @app.route('/index') def index(): ...
- 【python+selenium学习】常见错误: 'gbk' codec can't decode byte 0xb0 in position 30
最近编写的自动化脚本,数据部分使用到了从配置文件中取,即自定义config.ini,但是在读取配置文件的时候却报错了'gbk' codec can't decode byte 0xb0 in posi ...
- 用SWFUpload上传图片小例子
在开发项目中,经常会用到上传图片,接下来我就用一种简单的方式给大家分享一下使用SWFUpload的方式上传图片. 1.在网站根目录下新建一个SWFUpload文件夹,把下载的组建放在SWFUpload ...