如何定位和解决Andorid的内存溢出问题(大总结)

本文详细探讨了Android应用中的内存溢出问题,包括内存机制、内存溢出原因,尤其是内存泄露和大型对象(如Bitmap)引起的内存溢出。文章提供了常见的内存泄露场景及其解决方案,如静态成员变量引用、集合中的内存泄露、线程内部类的处理,以及资源对象未关闭等问题。此外,还讨论了如何通过调整Bitmap的使用和监听内存状态来减少内存压力。最后,介绍了使用DDMS和MAT工具进行内存泄漏检测和定位的方法。
摘要由CSDN通过智能技术生成

我们经常在做项目过程中遇到内存溢出的问题,同时面试中关于OOM的问题也常常出现。


这里,我将前辈们解决Andorid内存溢出的方法重新整理一番,方便自己以后使用。最后附上参考博文。


一、Android的内存机制

android应用层是由java开发的,android的davlik虚拟机与jvm也类似,只不过它是基于寄存器的。在java中,通过new为对象分配内存,所有对象在java堆内分配空间;而内存的释放是由垃圾收集器(GC)来回收的。 Java采用了有向图的原理。Java将引用关系考虑为图的有向边,有向边从引用者指向引用对象。线程对象可以作为有向图的起始顶点,该图就是从起始顶点(GC roots)开始的一棵树,根顶点可以到达的对象都是有效对象,GC不会回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被GC回收。


二、Android的内存溢出原因

1、内存泄露导致

由于我们程序的失误,长期保持某些资源(如Context)的引用,垃圾回收器就无法回收它,当然该对象占用的内存就无法被使用,这就造成内存泄露。

Android 中常见就是Activity被引用在调用finish之后却没有释放,第二次打开activity又重新创建,这样的内存泄露不断的发生,则会导致内存的溢出。

Android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的。Android为不同类型的进程分配了不同的内存使用上限,如果程序在运行过程中出现了内存泄漏的而造成应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉,这使得仅仅自己的进程被kill掉,而不会影响其他进程.
2、占用内存较多的对象

保存了多个耗用内存过大的对象(如Bitmap)或加载单个超大的图片,造成内存超出限制。

 

三、常见的内存泄漏问题及其解决方案


1、引用没释放造成的内存泄露

1.1注册没取消造成的内存泄露

 这种Android的内存泄露比纯Java的内存泄漏还要严重,因为其他一些Android程序可能引用系统的Android程序的对象(比如注册机制)。即使Android程序已经结束了,但是别的应用程序仍然还有对Android程序的某个对象的引用,泄漏的内存依然不能被垃圾回收。

1.2集合中对象没清理造成的内存泄露

我们通常把一些对象的引用加入到了集合中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。如果这个集合是static的话,那情况就更严重了

1.3 static

 staticJava中的一个关键字,当用它来修饰成员变量时,那么该变量就属于该类,而不是该类的实例。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值