.NET 常见内存泄漏

简介

以前认为,.NET程序内存都是托管的,如果不是调用非托管资源,应该不会存在内存泄漏的问题,但是,最近两天对归档程序内存使用分析,发现,事情不是想象的那么简单。

.NET内存泄漏,更准确的说应该是对象超过生命周期而不能被GC回收。本文列举了几种可能导致内存泄漏的情形,并提供示例代码,及解决方案,希望对大家有所帮助。

所举的例子都是经过自己极端简化过的,只是为了说明观点,具体项目中遇到的情形会复杂很多,需要具体分析。

事件注册后未解除注册

示例代码

程序运行时,内存使用情况如图:

原因分析

示例代码中,表面看起来,一次循环过后,上次new出来的对象a,不会继续被引用到,应该被视为垃圾,下次垃圾回收的时候,会被回收掉。但是,通过实验证明,对象a是不会被回收掉的。

原因是因为,对象b注册了click事件而未销毁,导致对象b会一直引用到a,a不会被视为垃圾被GC回收。

解决办法

对象a生命周期结束后,解除事件的注册,只有这样,a所占用的内存才会在下次垃圾回收的时候被回收掉。

下图为解除事件注册绑定后,内存的使用情况:

静态引用

示例代码

如果一直调用CreateObject方法,程序运行时,内存使用情况如图:

原因分析

静态变量的生命周期是全局的,即程序不退出,所占用的内存一直不会被释放掉。

解决办法

尽量少用静态成员,若一定要使用,注意静态成员引用的对象是否会一直增长。

控件不使用后未销毁

示例代码

程序运行时,内存使用情况如图:

原因分析

示例代码中,控件lbl已经被移除了,表面看起来,下次循环时,该控件应该被视为垃圾,在下次垃圾回收时,被回收掉。但实验证明,内存不会被回收掉。原因在于,控件未被真正销毁掉。

解决办法

控件生命周期结束之后,调用Dispose方法,确保控件能被真正销毁掉。

下图为调用Dispose方法后,内存的使用情况:

调用非托管资源而未释放

示例代码

原因分析

使用未托管对象之后忘记释放。

解决办法

对于实现了IDisposable接口的类可以使用using方式使用,或者显示调用Dispose方法。

工具

日志输出

穷人的工具,输出进程内存使用量 :)

任务管理器

通过观察任务管理器内存使用情况,查看是否存在内存泄露。

.NET Memory Profiler

专业的.NET性能调优工具,缺点,不是免费的 :)

参考

时间: 2024-11-05 16:42:10

.NET 常见内存泄漏的相关文章

Android 常见内存泄漏的解决方式

在Android程序开发中.当一个对象已经不须要再使用了,本该被回收时.而另外一个正在使用的对象持有它的引用从而导致它不能被回收.这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产生了. 内存泄漏有什么影响呢? 它是造成应用程序OOM的主要原因之中的一个.由于Android系统为每一个应用程序分配的内存有限.当一个应用中产生的内存泄漏比較多时.就难免会导致应用所须要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用Crash. 一.单例造成的内存泄漏 Android的单

JavaScript 中的内存泄漏

JavaScript 是一种垃圾收集式语言,这就是说,内存是根据对象的创建分配给该对象的,并会在没有对该对象的引用时由浏览器收回.JavaScript 的垃圾收集机制本身并没有问题,但浏览器在为 DOM 对象分配和恢复内存的方式上却有些出入. Internet Explorer 和 Mozilla Firefox 均使用引用计数来为 DOM 对象处理内存.在引用计数系统,每个所引用的对象都会保留一个计数,以获悉有多少对象正在引用它.如果计数为零,该对象就会被销毁,其占用的内存也会返回 给堆.虽然

Android 内存泄漏

在分享会上听小伙伴对这部分内容做了讲解,发觉在平时的编程中确实有很多问题没有注意到,故记录下来分享给各位,也欢迎各位不吝赐教纠正文中不足之处. 内存泄漏与内存溢出: 内存溢出简单讲就是程序运行要求的内存大于虚拟机能提供的最大内存,会导致程序崩溃,也就是我们常见的Out Of Memory错误. 内存泄露指程序未能释放已经不再使用的内存.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于程序设计的失误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费.少量的内存

android 内存泄漏检测工具 LeakCanary 泄漏金丝雀

韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha [email protected] 内存泄漏检测工具 android 内存泄漏检测工具 ======== 内存泄漏 就是  无用的对象没有被回收,占用着内存,使得可用内存变小了. 如何检测内存泄漏, 可以使用 LeakCanary来检测内存泄漏. leak  是 泄漏的意思.. Canary 是 金丝雀 的意思. 在运行 应用的时候, 泄漏金丝雀 如果检测到内存泄漏 会显示一个通知. ======== LeakCanary捕获

Android应用程序内存泄漏介绍

Android应用程序内存泄漏介绍 内存泄漏和内存溢出的区别 内存溢出(out of memory)是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory.比如在我们每个Android程序在运行时系统都会给程序分配一个一定的内存空间,当程序在运行中需要的内存超出这个限制就会报内存溢出(out of memory). 内存泄漏(memory leak)是指程序在申请内存后,无法释放已申请的内存空间.多次内存无法被释放,程序占用的内存会一直增加,直到超过系统的内存限制报内存

Android 性能篇 -- 带你领略Android内存泄漏的前世今生

基础了解 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费. Java 内存分配策略 Java 程序运行时的内存分配策略有三种,分别是 静态分配 . 栈式分配 和 堆式分配 ,对应的三种存储策略使用的内存空间主要分别是 静态存储区(也称方法区) . 栈区 和 堆区 . ?? 静态存储区(方法区):主要存放 静态数据 . 全局

Android 系统开发_内存泄漏篇 -- "内存泄漏"的前世今生

基础了解 什么是内存泄漏? 内存泄漏是当有程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存,由于程序逻辑错误而导致程序失去了对该内存的控制,使得内存浪费. Java 内存分配策略 Java 程序运行时的内存分配策略有三种,分别是?静态分配?.?栈式分配?和?堆式分配?,对应的三种存储策略使用的内存空间主要分别是?静态存储区(也称方法区)?.?栈区?和?堆区?. -?静态存储区(方法区):主要存放?静态数据?.?全局

Android开发 |常见的内存泄漏问题及解决办法

在Android开发中,内存泄漏是比较常见的问题,有过一些Android编程经历的童鞋应该都遇到过,但为什么会出现内存泄漏呢?内存泄漏又有什么影响呢? 在Android程序开发中,当一个对象已经不需要再使用了,本该被回收时,而另外一个正在使用的对象持有它的引用从而导致它不能被回收,这就导致本该被回收的对象不能被回收而停留在堆内存中,内存泄漏就产生了. 内存泄漏有什么影响呢?它是造成应用程序OOM的主要原因之一.由于Android系统为每个应用程序分配的内存有限,当一个应用中产生的内存泄漏比较多时

内存泄漏以及常见的解决方法

  之所以撰写这篇文章是由于前段时间花费了非常大的精力在已经成熟的代码上再去处理memory leak问题.写此的目的是希望我们应该养成良好的编码习惯,尽可能的避免这种问题,由于当你对着一大片的代码再去处理此类的问题,此时无疑添加了解决的成本和难度.准确的说属于补救措施了. 1. 什么是内存泄漏(memory leak)?  指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况.内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内