内存泄露是指变量或者对象在程序中不需要使用,但它还占用着内存空间
一般内存泄露发生的情况有如下两种:
1.在堆中申请的内存没有释放
2.对象已经不需要使用,但它还占用内存
C#和Java中有垃圾回收器,所以不存在第一种情况,而C++不存在垃圾回收机制,两种情况都存在。
但是C#,Java中也不是完全依赖于系统回收的,比如对于大型资源,数据库连接,网络连接和IO连接等,它也提供了手动的方式,比如Open()和Close(),Open创建一个连接并分配内存,Close方法关闭连接并释放内存。
在C#,Java中,引起内存泄露的原因还很多:
1.静态集合类,当数据被存放到静态集合类中,他们的生命周期就与程序一致,那么在程序结束之前就不能被释放,造成内存泄露。
2.上面所说的各种连接,数据库连接,网络连接和IO连接等,如果没有调用Close方法,会造成内存泄露
3.各种监听器。一个程序中往往用到很多监听器,如果在监听结束后还没有关闭监听器(Close方法),会造成内存泄露
4.变量不合理的作用域,例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Test { private string x; public void save() { x=get();//从网络获取数据保存到x save(x);//将x保存到文件中 } }
上面的x在函数结束后如果再不会被用到,而他的生命周期和程序一样,会造成内存泄露
5.单例模式也会造成内存泄露,例如:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class class1 { } class class2 { private class1 c1; private static class2 c2=new class2(new class1()); private class2(class1 c1) { this.c1 = c1; } public class2 get() { return c2; } }
class2中存在class1的引用,因为单例对象是以静态的方式被存储,所以生命周期是和程序一样,但是单例对象对Class1的引用有一个引用,所以Class1的对象不能被回收,造成内存泄露。