内存泄露示例:防止单例导致内存泄漏的实例// 使用了单例模式 public class AppManager { private static AppManager instance; private Context context; private AppManager(Context context) { this.context = context; } public static AppManager getInstance(Context context) { if (instance != null) { instance = new AppManager(context); } return instance; } } 12345678910111213141234567891011121314 2、非静态内部类创建静态实例造成的内存泄漏例如,有时候我们可能会在启动频繁的Activity中,为了避免重复创建相同的数据资源,可能会出现如下写法: public class MainActivity extends AppCompatActivity { private static TestResource mResource = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if(mResource == null){ mResource = new TestResource(); } //... } class TestResource { //... } } 123456789101112131415161718123456789101112131415161718 3、Handler造成的内存泄漏示例:创建匿名内部类的静态对象public class MainActivity extends AppCompatActivity { private final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // ... } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { // ... handler.sendEmptyMessage(0x123); } }); } } 1.什么是内存泄露? 内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 2.内存泄露的危害? 我们经常说申请了一段动态内存空间,那么就必须手动进行释放,假设不进行手动free的话,我们每次写一段程序就占用一个空间,那么总有一天是会用完的,那么我们写程序的意义又在哪里?讲句不好听的话就是占着茅坑不拉屎。 3.什么样的程序最怕内存泄露问题呢? 永远不会主动退出的程序(操作系统、杀毒软件、服务器程序):常驻(内存)进程(程序),出现内存泄漏会导致响应越来越慢,最终卡死。 内存泄漏几乎是很难避免的,不管是老手还是新手,都存在这个问题。甚至包括windows, Linux 这类软件,都或多或少有内存泄漏。也许对于一般的应用软件来说,这个问题似乎不是那么突出,重启一下也不会造成太大损失。但是如果你开发的是嵌入式系统软件呢?比如汽车制动系统,心脏起搏器等对安全要求非常高的系统。你总不能让心脏起搏器重启吧,人家阎王老爷是非常好客的。 下面我们来简单的看一个内存泄露的情形:#includeint main() { while (1) { malloc(1); } return 0; } 12345678910111234567891011 接下来我们来查找任务管理器中内存的使用情况:初始的使用情况: 接下来我们再VS中运行一下这个程序: 我们可以看到最终它的内存使用量达到了9.2就趋于平稳了,这是系统的保护机制,难不成还真让你把内存使用完了,那这电脑不就没法用了嘛哈哈,自己可以动手试试,你会发现在执行程序时确实是从7.4一直增长到9.2,最后趋于稳定的。当然每个人的电脑内存情况会稍有不同,但是观察的现象确实很明显的。所以我们在开辟空间结束时,一定要记得释放这段空间还给操作系统;俗话说:有借有还,再借不难。 4.如何来避免内存泄露呢? 内存泄漏非常常见,解决方案分为两种:1、事前预防型。如智能指针等。 2、事后查错型。如泄漏检测工具。 3.工程前期良好的设计规范,养成良好的编码规范,申请的内存空间一定要记着匹配的去释放,但是如果碰上异常时,就算注意释放了,还是可能会出问题,这就需要下一条智能指针来管理才有保证。 4.采用RAII思想或者智能指针来管理资源。 5.有些公司内部规范使用内部实现的私有内存管理库,这套库自带内存泄漏检测的功能选项,出问题了可以使用内存泄漏工具检测,不过很多工具都不够靠谱或者收费昂贵。 1.长生命周期的对象,持有短生命周期的引用 解决办法: 尽量降低变量的作用域,以及及时把对象修改为可清理对象(null)。 2. 资源未关闭造成的内存泄漏 解决办法: 及时的关闭资源。 3.不再用的对象,没有及时的把它的引用从集合中清理掉 解决办法: 退出程序之前,将集合里的东西clear,然后置为null,再退出程序。 4.资源未关闭造成的内存泄漏 在各种IO或者数据库连接时,都需要在最后通过close()方法释放对象,如果没有使用close()方法可能会导致内存泄漏。 解决办法: 及时的关闭资源。 5.集合中的内存泄露 我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,却没有及时的把它的引用从集合中清理掉,这样这个集合就会越来越大。 解决方法: 在退出程序之前,将集合里的东西clear,然后置为null,再退出程序。