1.什么是内存泄漏?

Java 中的内存泄漏是指应用程序不再需要的对象在 Java 虚拟机 (JVM) 中仍然存在的状态。通俗来讲就是生命周期长的对象持有生命周期短的对象,导致GC无法回收本该需要回收的对象。

2.造成内存泄露的原因有哪些?

(1)非静态内部类造成的内存泄漏

那么为什么非静态内部类会造成内存泄漏呢?

看个例子

public class Outer {private String TAG="Outer";private Runnable runnable = new Runnable(){public void run(){System.out.println("inner run: " + TAG);}};
}

通过javac Outer.java 我们得到两个class文件

Outer.class

public class Outer {private String TAG = "Outer";private Runnable runnable = new Runnable() {public void run() {System.out.println("inner run: " + Outer.this.TAG);}};public Outer() {}
}

Outer$1.class

class Outer$1 implements Runnable {Outer$1(Outer var1) {this.this$0 = var1;}public void run() {System.out.println("inner run: " + this.this$0.TAG);}
}

看到没有,在Outer$1.class中,Outer$1是Runnable,我们可以看到在Outer$1类函数中,传了外部类Outer对象,this.this$0是指向Outer对象。Outer$1持有Outer,也就是Runnable持有Outer。

结论:非静态内部类持有外部类的引用

看下静态内部类:

public class Outer {private static String TAG="Outer";private static Runnable runnable = new Runnable(){public void run(){System.out.println("inner run: " + TAG);}};
}

通过javac Outer.java命令

我们看到Outer$1.class

class Outer$1 implements Runnable {Outer$1() {}public void run() {System.out.println("inner run: " + Outer.TAG);}
}

我们可以得到Outer$1并没有Outer,所以静态内部类不持有外部类。

解决方案:使用静态内部类替换内部类解决非静态内部类造成的内存泄漏。

(2)单例造成的内存泄漏

public class SingleInstance {private Context context;private static SingleInstance instance;private SingleInstance(Context context) {this.context = context.getApplicationContext();}public static SingleInstance getInstance(Context context) {if (instance == null) {synchronized (SingleInstance.class) {if (instance == null) {instance = new SingleInstance(context);}}}return instance;}}

如果 SingleInstance.getInstance(context)传入的是Activity的context,那么该Activity就会被单例对象所持有,他的生命周期等于整个应用程序的生命周期,当Activity退出了就不会被回收,造成了内存泄漏。

如果传入的是 Application 的 Context,因为 Application 的生命周期就是整个应用的生命周期,这样是没有问题的。

3)Handler造成的内存泄漏
   1.匿名内部类:

Handler handler=new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);}
};

2.非静态内部类(同上面的非静态内部类造成的内存泄漏)

protected class AppHandler extends Handler {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {}}}

解决方案:静态内部类+弱引用

  private static class MyHandler extends Handler {WeakReference<Activity> activity;MyHandler(Activity activity){this.activity=new WeakReference<Activity>(activity);}public void handleMessage(Message message){switch (message.what){}}}

当Activity销毁的时

   // 清空消息队列,移除对外部类的引用@Overrideprotected void onDestroy() {super.onDestroy();mHandler.removeCallbacksAndMessages(null);}

(4)资源对象使用后未及时关闭

广播BraodcastReceiver文件流Fire图片资源Bitmap数据库游标等在Activity/Fragment的onDestory方法内要关闭掉。

3、内存泄漏的危害

1.一次的内存泄漏可能看不出来什么影响,但是较多的内存泄漏会造成应用卡顿。因为系统分配给每个应用的内存是有限的,内存泄漏会导致其他组件的可用内存变少,一方面系统GC频率变高,GC时所有进程都会等待,会造成系统变卡顿。另一方面内存变少,可能使得系统额外分配给该对象一些内存,而影响整个系统的运行情况

2、导致程序运行崩溃(OOM):一旦内存不足以为某些对象分配所需要的空间,将会导致程序崩溃,造成体验进一步变差。

4.如何来检测内存溢出的情况呢?

见上一篇文章:leakCanary检测内存泄漏的原理(持续更新)_程序猿yz的博客-CSDN博客_leakcanary

本文参考了:为啥非静态内部类能持有外部类? - 腾讯云开发者社区-腾讯云

内存泄漏和内存溢出以及原因和解决方案相关推荐

  1. 内存溢出和内存泄漏的区别、产生原因以及解决方案

    内存溢出和内存泄漏的区别.产生原因以及解决方案 参考文章: (1)内存溢出和内存泄漏的区别.产生原因以及解决方案 (2)https://www.cnblogs.com/ziyoublog/p/1038 ...

  2. 内存溢出和内存泄漏的区别、产生原因以及解决方案 转

    内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出. ...

  3. 内存溢出和内存泄漏的区别,产生原因以及解决方案

    一.概念与区别 内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory:比如申请了一个integer,但给它存了long才能存下的数,那 ...

  4. python会不会出现内存泄露_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

  5. 内存泄漏和内存溢出的关系和区别

    作者:不怕天黑_0819 链接:https://www.jianshu.com/p/61d34df7eabe 一.内存泄漏(memory leak) 1.内存泄漏是指程序中已动态分配的堆内存由于某种原 ...

  6. java 内存溢出 内存泄露_JVM——内存泄漏与内存溢出

    1.内存溢出 1.1 什么是Java的内存溢出? 在Java程序运行的过程中,经常会碰到以下错误:java.lang.OutOfMemoryError. 通俗讲,内存溢出是指程序在申请内存时,没有足够 ...

  7. 段错误、内存泄漏、内存溢出、堆溢出、栈溢出

    参考:内存泄漏.内存溢出.段错误.堆溢出.栈溢出 作者:焦木白 发布时间:2019-10-22 网址:https://blog.csdn.net/jiaomubai/article/details/1 ...

  8. java内存泄漏和内存溢出_Java和内存泄漏

    java内存泄漏和内存溢出 总览 术语"内存泄漏"在Java中的使用方式不同于在其他语言中使用的方式. 通用术语中的"内存泄漏"是什么意思,在Java中如何使用 ...

  9. python会内存泄漏吗_Python内存泄漏和内存溢出的解决方法

    Python内存泄漏和内存溢出的解决方法 发布时间:2020-10-30 23:08:34 来源:亿速云 阅读:92 作者:Leah 这篇文章将为大家详细讲解有关Python内存泄漏和内存溢出的解决方 ...

  10. python 内存溢出能捕获吗_Python内存泄漏和内存溢出的解决方案

    一.内存泄漏 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题. 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是 ...

最新文章

  1. 4D毫米波雷达Radar
  2. 加码 2000 亿还不够,阿里云再建三座超级数据中心加速新基建
  3. VS2013无法启动IIS Express Web的解决办法
  4. Vue 第一天学习 ---2018.06.28
  5. PAT1052 卖个萌 (20 分)【别人的代码 借鉴从字符串中截取特定部分的思路】
  6. Mapgis6.7 林相图自动注记 .
  7. Java面试题 20在面向对象编程里,经常使用is-a来说明对象之间的继承关系
  8. 查询错误_三菱PLC快捷查询错误代码(全)
  9. react循环key值_01 React快速入门(一)——使用循环时对于‘key’报错处理
  10. libsvm 参数以及计算测试点相似度
  11. 服务器系列和酷睿系列,三大系列 从英特尔主流处理器选择服务器(2)
  12. SQLyog——下载2058问题
  13. ArcGIS符号库下载 | 制图规范、三调、1:1万地形图、土地利用总体规划图.....
  14. 一种标准地图服务转矢量Shapefile方法
  15. Android教父高焕堂谈Android“开源”与“兼容”
  16. 对比只适用于有两个或多于两个层次的因子
  17. 关注智能眼镜:tooz Devkit 20
  18. JSP环境的搭建及程序初步
  19. Android 之 APP上架应用宝平台
  20. gcc常用命令与gcc编译器背后的故事

热门文章

  1. android字体有些显示不正常显示,为什么iconfont字体图标在安卓机上显示不出来
  2. C语言自定义类型详解!
  3. 一起来创建一个无向图吧!
  4. 从一个ELF程序的加载窥探操作系统内核-(5)
  5. EasyPlayer播放H.265视频,播放器快照时间显示的问题优化
  6. android RadioGroup位置,android RadioGroup
  7. 一本通与众不同_是什么使电子商务设计与众不同?
  8. linux服务器状态查看命令,Linux服务器操作系统查看命令
  9. Win10 端口被占用解决方案
  10. iptables 打开端口_如何在iptables中打开端口?