Skip to content

Latest commit

 

History

History
119 lines (50 loc) · 3.24 KB

内存泄漏&内存溢出.md

File metadata and controls

119 lines (50 loc) · 3.24 KB

1.什么是OOM & 什么是内存泄漏以及原因

内存泄漏

什么是

没有用的对象资源任与GC-Root保持可达路径,导致系统无法进行回收。

原因

1 非静态内部类默示持有外部类的引用,如非静态handler持有activity的引用

2.接收器、监听器注册没取消造成的内存泄漏,如广播,eventsbus

3.Activity 的 Context 造成的泄漏,可以使用 ApplicationContext

4.单例中的static成员间接或直接持有了activity的引用

5.资源对象没关闭造成的内存泄漏(如: Cursor、File等)

6.全局集合类强引用没清理造成的内存泄漏(特别是 static 修饰的集合)

内存溢出

根据java的内存模型会出现内存溢出的内存有堆内存、 方法区内存、虚拟机栈内存、native方法区内存, 一般说的OOM基本都是针对堆内存;

1、对于堆内存溢出主的根本原因有两种

(1)app进程内存达到上限

(2)手机可用内存不足,这种情况并不是我们app消耗了很多内存, 而是整个手机内存不足

2、对于app内存达到上限只有两种情况

(1)申请内存的速度超出gc释放内存的速度.往内存中加载超大文件,加载的文件或者图片过大造成或者循环创建大量对象

(2)内存出现泄漏,gc无法回收泄漏的内存,导致可用内存越来越少

2.Thread是如何造成内存泄露的,如何解决?

垃圾回收器不会回收GC Roots以及那些被它们间接引用的对象

非静态内部类会持有外部类的引用。Thread 会长久地持有 Activity 的引用,使得系统无法回收 Activity 和它所关联的资源和视图。


使用静态内部类/匿名类,不要使用非静态内部类/匿名类。

该养成为thread设置退出逻辑条件的习惯。

3. Handler导致的内存泄露的原因以及如何解决

原因:1.Java中非静态内部类和匿名内部类都会隐式持有当前类的外部引用

2.我们在Activity中使用非静态内部类初始化了一个Handler, 此Handler就会持有当前Activity的引用。

3.我们想要一个对象被回收,那么前提它不被任何其它对象持有引用, 所以当我们Activity页面关闭之后,存在引用关系: "未被处理 / 正处理的消息 -> Handler实例 -> 外部类", 如果在Handler消息队列 还有未处理的消息 / 正在处理消息时 导致Activity不会被回收,从而造成内存泄漏

解决方案: 1.将Handler的子类设置成 静态内部类,使用WeakReference弱引用持有Activity实例

2.当外部类结束生命周期时,清空Handler内消息队列

4.如何加载Bitmap防止内存溢出

1.对图片进行内存压缩;

2.高分辨率的图片放入对应文件夹;

3.内存复用

4.及时回收

5.MVP中如何处理Presenter层以防止内存泄漏的

首先 MVP 会出现内存泄漏是因为 Presenter 层持有 View 对象,一般我们会把 Activity 做为 View 传递到 Presenter,Presenter 持有 View对象,Activity 退出了但是没有回收出现内存泄漏。

解决办法: 1.Activity onDestroy() 方法中调用 Presenter 中的方法,把 View 置为 null

2.使用 Lifecycle