Android系统优化OOM问题分析

合集下载

Android进阶实现性能优化之OOM与Leakcanary详解原理

Android进阶实现性能优化之OOM与Leakcanary详解原理

Android进阶实现性能优化之OOM与Leakcanary详解原理⽬录Android内存泄漏常见场景以及解决⽅案资源性对象未关闭注册对象未注销类的静态变量持有⼤数据单例造成的内存泄漏⾮静态内部类的静态实例Handler临时性内存泄漏容器中的对象没清理造成的内存泄漏WebView使⽤ListView时造成的内存泄漏Leakcanaryleakcanary 导⼊leakcanary 是如何安装的leakcanary 如何监听Activity、Fragment销毁RefWatcher 核⼼原理流程图本⽂主要探讨以下⼏个问题:Android内存泄漏常见场景以及解决⽅案Leakcanary 使⽤及原理Android内存泄漏常见场景以及解决⽅案资源性对象未关闭对于资源性对象不再使⽤时,应该⽴即调⽤它的close()函数,将其关闭,然后再置为null。

例如Bitmap等资源未关闭会造成内存泄漏,此时我们应该在Activity销毁时及时关闭。

注册对象未注销例如BraodcastReceiver、EventBus未注销造成的内存泄漏,我们应该在Activity销毁时及时注销。

类的静态变量持有⼤数据对象尽量避免使⽤静态变量存储数据,特别是⼤数据对象,建议使⽤数据库存储。

单例造成的内存泄漏优先使⽤Application的Context,如需使⽤Activity的Context,可以在传⼊Context时使⽤弱引⽤进⾏封装,然后,在使⽤到的地⽅从弱引⽤中获取Context,如果获取不到,则直接return即可。

⾮静态内部类的静态实例该实例的⽣命周期和应⽤⼀样长,这就导致该静态实例⼀直持有该Activity的引⽤,Activity的内存资源不能正常回收。

此时,我们可以将该内部类设为静态内部类或将该内部类抽取出来封装成⼀个单例,如果需要使⽤Context,尽量使⽤Application Context,如果需要使⽤Activity Context,就记得⽤完后置空让GC可以回收,否则还是会内存泄漏。

oom解决方案

oom解决方案

oom解决方案《解决OOM问题的有效方法》OOM(Out of Memory)是指程序在执行过程中耗尽了所有可用的内存资源,导致系统无法继续正常运行的问题。

在大型软件开发中,OOM问题是一个常见且具有挑战性的难题,需要开发人员采取有效的解决方法来应对。

针对OOM问题,下面提供一些有效的解决方案:1. 内存泄漏排查:首先要排查程序中是否存在内存泄漏的情况。

内存泄漏是指程序分配了内存空间,但在不再需要的情况下没有释放该内存空间,导致内存资源被长时间占用而无法释放。

通过内存泄漏排查工具,可以帮助开发人员找出内存泄漏的位置,并进行相应的修复。

2. 增加内存资源:如果程序的内存需求超过了系统当前可用的内存资源,可以考虑增加系统的内存资源。

通过升级硬件或者优化系统内存配置,可以增加程序可用的内存空间,从而缓解OOM问题。

3. 优化程序性能:对程序进行性能优化是解决OOM问题的重要手段。

通过减少内存占用、优化算法等方式,可以降低程序的内存需求,从而减少出现OOM的可能性。

4. 使用内存管理工具:借助内存管理工具,可以对程序的内存使用情况进行监控和管理。

通过实时监控内存使用情况,并对内存使用进行优化,可以有效地避免OOM问题的发生。

5. 分析堆转储文件:当程序发生OOM时,可以通过生成堆转储文件进行分析。

堆转储文件可以帮助开发人员了解程序在OOM发生时的内存状态,从而更好地定位和解决OOM问题。

总之,解决OOM问题需要综合考虑程序本身的内存使用情况、系统资源配置以及程序性能优化等方面的因素。

只有通过有效的手段和方法,才能更好地应对和解决OOM问题,确保程序能够稳定可靠地运行。

Android避免内存溢出(OutofMemory)方法总结

Android避免内存溢出(OutofMemory)方法总结

of Memory)方法总Android避免内存溢出(Out结避免内存溢出的方法,主要是对以下三个方面对程序进行优化武汉Android培训内存引用在处理内存引用之前,我们先来复习下什么是强引用、软引用、弱引用、虚引用强引用:强引用是使用最普遍的引用。

如果一个对象具有强引用,那垃圾回收器绝不会回收它。

当内存空间不足,Java 虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。

软引用:如果一个对象只具有软引用,但内存空间足够时,垃圾回收器就不会回收它;直到虚拟机报告内存不够时才会回收,只要垃圾回收器没有回收它,该对象就可以被程序使用。

软引用可用来实现内存敏感的高速缓存。

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。

弱引用:只具有弱引用的对象拥有更短暂的生命周期。

在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存。

不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。

弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。

虚引用:虚引用可以理解为虚设的引用,与其他几种引用都不同,虚引用并不会决定对象的生命周期。

如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用主要用来跟踪对象被垃圾回收器回收的活动。

虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。

当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。

安卓系统开发的常见问题与解决方案梳理

安卓系统开发的常见问题与解决方案梳理

安卓系统开发的常见问题与解决方案梳理安卓系统开发是目前热门的技术领域,不少程序员都想要探究其中的奥秘。

然而在开发过程中,总会遇到各种各样的问题,如:应用启动慢,内存泄漏,OOM(Out Of Memory),ANR (Application Not Responding),热修复等。

这些问题都给安卓开发者带来了不少困扰,下面针对这些常见问题,为大家提供一些解决方案。

1. 应用启动慢应用启动慢是安卓系统开发中常见的问题,尤其是在应用内部需要大量初始化操作的情况下。

针对这种情况,开发者可以采用延迟初始化的方式,即在应用启动后通过异步线程进行初始化,从而提高应用启动速度。

此外,还可以通过减少应用的启动流程,缩短冷启动时间,提高用户体验。

2. 内存泄漏内存泄漏是安卓开发者面临的另一个大问题,它会导致应用崩溃或者占用过多的内存,从而影响应用的性能和稳定性。

针对这种情况,开发者可以通过使用Android Studio提供的Profiler工具来查找内存泄漏。

另外,还可以通过及时释放资源、避免对象引用循环等方式来避免内存泄漏。

3. OOM(Out Of Memory)OOM指的是内存不足,是安卓开发者常常面对的问题。

当应用占用的内存超过了系统规定的阈值时,就会出现OOM问题。

为了避免OOM,可以采用如下解决方案:- 及时释放无用资源或变量- 使用弱引用- 限制图片的大小和数量- 通过调整内存大小等方式优化应用性能4. ANR(Application Not Responding)ANR是指应用无响应,在应用响应超过五秒钟时,就会发出ANR警告。

这种情况通常是因为应用在主线程执行了耗时操作,从而导致主线程被阻塞。

为了避免ANR,可以采用如下解决方案:- 减少主线程的工作量- 使用异步线程处理耗时操作- 使用Handler、Message、AsyncTask等机制避免主线程被阻塞5. 热修复热修复是指在应用运行期间,针对线上应用中的某些错误,通过修复行动来快速修复,从而避免应用的重发版本。

案例实战(八)一个数据同步系统频繁OOM内存溢出的排查实践

案例实战(八)一个数据同步系统频繁OOM内存溢出的排查实践

案例实战(⼋)⼀个数据同步系统频繁OOM内存溢出的排查实践案例背景⾸先说⼀下案例背景,线上有⼀个数据同步系统,是专门负责从另外⼀个系统去同步数据的,简单来说,另外⼀个系统会不停的发布⾃⼰的数据到Kafka中去,然后我们有⼀个数据同步系统就专门从Kafka⾥消费数据,接着保存到⾃⼰的数据库中去,⼤概就是这样的⼀个流程。

我们看下图,就是这个系统运⾏的⼀个流程。

结果就这么⼀个⾮常简单的系统,居然时不时就报⼀个内存溢出的错误,然后就得重启系统,过了⼀段时间⼜会再次内存溢出⼀下。

⽽且这个系统处理的数据量是越来越⼤,因此我们发现他内存溢出的频率越来越⾼,到这个情况,就必须要处理⼀下了。

经验丰富的⼯程师:从现象看到本质⼀般遇到这种现象,只要是经验丰富的⼯程师,应该已经可以具备从现象看到本质的能⼒了。

我们可以来分析和思考⼀下,既然每次重启过后都会在⼀段时间以后出现内存溢出的问题,说明肯定是每次重启过后,内存都会不断的上涨。

⽽且⼀般要⾼到 JVM 出现内存溢出,通常就是两种情况,要不然是并发太⾼,瞬间⼤量并发创建过多的对象,导致系统直接崩溃了。

要不就是有内存泄漏之类的问题,就是很多对象都赖在内存⾥,⽆论你如何GC就是回收不掉。

那么这个场景是怎么回事呢?我们当时分析了⼀下,这个系统的负载并不是很⾼,虽然数据量不少,但并不是那种瞬时⾼并发的场景。

这么看来,很可能就是随着时间推移,有某种对象越来越多,赖在内存⾥了。

然后不断的触发gc,结果每次gc都回收不掉这些对象。

⼀直到最后,内存实在不⾜了,就会内存溢出我们看看下⾯的图,在下图⾥就画出了这个问题。

通过 jstat 来确认我们的推断接着直接在⼀次重启系统之后,⽤jstat观察了⼀下JVM运⾏的情况:我们发现,⽼年代的对象⼀直在增长,不停的在增长。

每次Young GC过后,⽼年代的对象就会增长不少。

⽽且当⽼年代的使⽤率达到 100% 之后,我们发现会正常触发 Full GC,但是 Full GC 根本回收不掉任何对象,导致⽼年代使⽤率还是100%!然后⽼年代使⽤率维持100%⼀段时间过后,就会报内存溢出的问题,因为再有新的对象进⼊⽼年代,实在没有空间放他了!所以这就基本确认了我们的判断,每次系统启动,不知道什么对象会⼀直进⼊堆内存,⽽且随着Young GC执⾏,对象会⼀直进⼊⽼年代,最后触发Full GC都⽆法回收⽼年代的对象,最终就是内存溢出。

记一次线上OOM问题分析与解决

记一次线上OOM问题分析与解决

记⼀次线上OOM问题分析与解决⼀、问题情况最近⽤户反映系统响应越来越慢,⽽且不是偶发性的慢。

根据后台⽇志,可以看到系统已经有oom现象。

根据jdk⾃带的jconsole⼯具,可以监视到系统处于堵塞时期。

cup占满,活动线程数持续增加,堆内存接近峰值。

⼆、分析情况使⽤jconsole分析:找到jdk安装路径,点击bin⽬录下的jconsole.exe,运⾏。

当时线上情况是堆内存使⽤量7个G左右,接近峰值;活动线程80个左右;CPU占⽤率80%左右。

系统随时可能宕机。

根据⽤户反映的情况,系统每隔⼀段时间都会卡顿,且堆内存是⼀段时间上升,然后突然下降,再上升,所以我第⼀反应是:会不会是系统频繁的进⾏FullGC,导致系统在⼀段时间内不可⽤?⾸先认识⼀下什么是Full GC(需要⼀定的java内存模型知识):含义:FullGC是发⽣在永久代和⽼年代的⼀种垃圾回收机制。

触发条件:⽼年代内存满时。

特点:执⾏时间长,期间系统不可⽤。

于是查看⽼年代占⽤情况:使⽤期间⽼年代内存峰值已经达到7个G左右,接近上限。

貌似有点坏⽓息的味道。

于是⽤jstat -gc pid查看gc回收情况:案发当时Full GC执⾏次数为28次,总执⾏时长为27秒。

可以实锤是频繁Full GC导致系统线程堵塞。

上⾯介绍到了,⽼年代内存满时会触发FullGC,那么哪种情况下会进⼊⽼年代呢?(1)对象在新⽣代中经历固定次数minor GC,会进⼊⽼年代可通过-XX:MaxTenuringThreshold设置,默认15(2)当新⽣代中minor GC回收后,存活对象⼤于survivor to区容量时,进⼊⽼年代(3)⼤对象直接进⼊⽼年代可通过-XX:PretenureSizeThreshold 设置使⽤jvisualvm分析:在jdk的bin⽬录下,找到jvisualvm.exe,点击运⾏。

这⾥可以很清楚的看到堆内存的内容分布情况。

当时系统是byte[]和InternalAprOutputBuffer占⽤内存最⼤,同为2.9G。

智能手机操作系统性能分析及优化策略

智能手机操作系统性能分析及优化策略

智能手机操作系统性能分析及优化策略随着智能手机在我们的日常生活中越来越占据重要地位,对于智能手机操作系统的需求也变得越来越高。

对于操作系统来说,性能一直是用户关注的重点。

因此,本文将从操作系统的角度出发,分析智能手机的性能问题,并提出相关的优化策略。

第一章 Android操作系统性能分析由于Android操作系统市场占有率最高,因此我们首先对Android操作系统进行性能分析。

1.1. 系统启动时间过长当用户按下手机的开机键时,Android操作系统需要启动一系列的程序和服务。

这些服务可能包括加载应用程序、启动蓝牙服务等。

由于Android系统启动的服务较多,因此,系统的启动时间相对较长。

但是,如果启动时间过长,可能会影响用户的体验。

因此,我们需要针对系统启动时间过长的问题提出优化策略。

优化策略:(1)通过关闭不必要的服务程序,减少系统启动时的负担。

(2)将某些服务延迟加载,减少其对启动速度的影响。

1.2. 应用程序启动时间过长当用户启动某个应用程序时,Android系统需要加载一些依赖库文件和资源。

如果应用程序启动时间过长,用户会感到不太满意。

因此,针对应用程序启动时间过长的问题,我们需要找出原因,并提出优化策略。

优化策略:(1)通过优化应用程序的代码,减少加载时间。

(2)将应用程序相关的所有参数和文件缓存到内存中,在下次启动时从缓存中读取,加快启动速度。

1.3. UI响应速度慢当用户滑动应用程序的界面时,应用程序需要及时响应,否则用户会感到疲劳。

然而,如果界面响应速度慢,用户的体验会受到很大的影响。

因此,我们需要针对UI响应速度慢的问题提出优化策略。

优化策略:(1)通过优化界面代码,减少代码执行时间。

(2)将能够异步加载的操作异步化,减轻UI线程的压力,从而加快页面响应速度。

第二章 iOS操作系统性能分析除了Android操作系统外,iOS操作系统也是目前最受欢迎的手机操作系统之一。

因此,我们也需要对iOS操作系统进行性能分析。

OOM异常产生的原因和处理方法

OOM异常产生的原因和处理方法

OOM异常产⽣的原因和处理⽅法⼀般⽽⾔,android中常见的原因主要有以下⼏个:1.数据库的cursor没有关闭。

2.构造adapter没有使⽤缓存contentview。

3.调⽤registerReceiver()后未调⽤unregisterReceiver().4.未关闭InputStream/OutputStream。

5.Bitmap使⽤后未调⽤recycle()。

6.Context泄漏。

7.static关键字等。

接下来分别对这些溢出情况说出解决的思路:1.针对数据库cursor没有关闭的情况,如果我们查询数据库得到的数据量⽐较⼩的话是不会造成内存溢出的,但是如果太⼤的话就容易发⽣这种异常,所以当我们在使⽤完Cursor的时候就应该⼿动调⽤它的close⽅法关闭cursor.2.针对adapter没有复⽤convertView的情况,在我们开发的过程中,经常会遇到⼀个listview加载成百上千条的数据,如果不复⽤convertView的话就会在每次执⾏getView⽅法的时候都创建⼀个新的对象,⽽这个⽅法的调⽤速度⼜是很快的,java不能够及时的回收内存就会造成OOM异常,这时候除了要在getView⽅法⾥⾯对convertView进⾏判断后复⽤,还应该使⽤ViewHolder类来保存通过过findViewById得到的⼦控件地址值.3.在activity中注册了⼴播,但是在activity退出的时候没有取消注册的话可能会造成内存溢出,需要⼿动的在相应的位置进⾏反注册.4.不关闭输⼊输出流的话就相当于在内存和硬盘⼀直存在着连接占⽤着资源,当其他操作需要资源时就会造成内存溢出.5.位图在安卓中占⽤的内存是很⼤的,使⽤后如果不及时回收的话会占⽤⼤量空间,所以针对位图的操作⼀般有如下解决⽅案:1)及时的调⽤resycle⽅法来⼿动的回收;2)设置采样率,有时候我们不⼀定要把图⽚完全显⽰出来,这时候就要按⽐例来缩放,在我们得到采样率的时候就可以将图⽚缩⼩后再进⾏加载,节省⼤量的内存;3)使⽤软引⽤.6.上下⽂泄露例如在activity中使⽤了线程内部类,这时候在线程内存就会保存⼀个activity的引⽤,当activity被销毁的时候,线程仍在执⾏的话就容易造成oom,因为此时的activity的引⽤仍然存在没有被释放,那么这个activity就仍然没有从内存中被gc.7.static关键字开发中使⽤关键字static可以将成员变量和⽅法变成类变量和类⽅法,这样会⼤⼤延长变量的⽣命周期,如果我们过多的使⽤static来保存占⽤资源过多的对象的引⽤就会造成内存溢出,⽐如⽤static修饰⼀个上下⽂的对象的话.第⼀,应该尽量避免static成员变量引⽤资源耗费过多的实例,⽐如Context。

记录一次OOM的排查过程以及内存分析、解决方案

记录一次OOM的排查过程以及内存分析、解决方案

记录⼀次OOM的排查过程以及内存分析、解决⽅案 在测试环境中开启的堆⼤⼩是4g。

但是却发⽣了OOM。

发⽣OOM的场景是:上传Excel 之后进⾏数据的清洗,然后清洗完成之后会将清洗掉的、清洗后的数据再次备份到磁盘中;同时将清洗后的数据⼊关系型数据库。

(解析Excel ⽤的是POI,数据清洗⽤的是Tablesaw,且清洗的操作都是在内存中处理的) 记录下此次OOM的排查过程。

1. 前置知识 关于JVM调试的前置知识。

0. 抛出OOM的前提The parallel collector throws an OutOfMemoryError if too much time is being spent in garbage collection (GC): If more than 98% of the total time is spent in garbage collection and less than 2 1. 内存区域JVM的内存区域分为五块,随线程消亡的包括本地⽅法栈、虚拟机栈(栈)、PC(程序计数器),线程共享的区域包括:堆、⽅法区(JDK7的永久代,JDK8的MetaSpace元空间)。

-Xms2g 可以指定初始化堆的⼤⼩,-Xmx2g可以指定最⼤堆的⼤⼩。

其中堆分为新⽣代(Eden区、From Survivor区和To Survivor)、⽼年代。

新⽣代和⽼年代的⽐例默认是1:2,也就是新⽣代占堆的1/3,⽼年代占堆的2/3(–XX:NewRatio可以调节新⽣代和⽼年代⽐例)。

新⽣代Eden和两个Survivor的⽐例是8:1:1。

(–XX:SurvivorRatio可以调节E区和两个S区⽐例)。

不指定-Xms 初始化堆⼤⼩的情况下初始化是机器内存的1/64 ,最⼩是8m。

不指定-Xmx 最⼤堆的⼤⼩是1/4 机器内存。

查看默认的初始堆和最⼤堆的⼤⼩:我的机器是16G运⾏内存C:\Users\xxx>java -XX:+PrintFlagsFinal -version | findstr HeapSizeuintx ErgoHeapSizeLimit = 0 {product}uintx HeapSizePerGCThread = 87241520 {product}uintx InitialHeapSize := 264241152 {product}uintx LargePageHeapSizeThreshold = 134217728 {product}uintx MaxHeapSize := 4206886912 {product}换成M之后InitialHeapSize 是 252 m, MaxHeapSize 是 4012 M也可以⽤java 程序查看总堆以及剩余的堆内存:long totalMemory1 = Runtime.getRuntime().totalMemory();long freeMemory1 = Runtime.getRuntime().freeMemory(); 另外JVM 有两种模式,client模式和server 模式。

Android开发OOM异常

Android开发OOM异常

Android开发中如何避免OOM异常?翡翠教育-Android开发培训1、加载图片对内存的影响在Android开发中,加载图片很容易的碰到OOM。

何为OOM? OOM, 即out of memory,这里面的memory指的是堆内存。

因为在Android中,应用程序都是有一定的内存限制的。

当内存占用过高就容易出现OOM异常。

我们可以通过下面的代码看出每个应用程序最高可用内存是多少:那为什么要特别重视图片内存的占用呢?我们来看一下一张图片能占多少内存吧。

举个例子,当我们加载一张分辨率为1960*1200,色彩模式为ARGB_8888,图片大小为4M的图片时,其所占用的内存空间并不是图片的大小,而是根据图片的分辨率来计算的。

这张图片需要的内存为:1960*1200*4(bit) / 1024 / 1024 = 8.79MB一张图片就占用了将近9M,如果是一组图片呢?可以想象的到,如果我们在加载图片的时候使用原图加载的话,程序分分钟就死掉了。

因此,在展示高分辨率图片的时候,最好先将图片进行压缩。

压缩后的图片大小应该和用来展示它的控件大小相近,毕竟在一个很小的ImageView上显示一张超大的图片不会带来任何视觉上的好处,但却会占用我们相当多宝贵的内存,而且在性能上还可能会带来负面影响。

2、降低图片内存占用——压缩图片从上节来看,影响一张图片占用内存的有两方面的因素,(1)压缩尺寸(2)色彩模式;从色彩模式的角度,对于一个ARGB_8888的图片,在满足业务需求的情况下,比如并不要求这张图片特别清晰逼真,那么可以在压缩尺寸之前,可以同时将option的值重新设置一下,比如设置为RGB_565。

ARGB_8888,表示一个像素占8+8+8+8=32位=4字节,而RGB_565,表示一个像素占用5+6+5=16位=2字节。

这样设置之后图片内存占用会减半。

下面重点来看一下尺寸方面的压缩。

如何对一张大图片进行适当的压缩,让它能够以最佳大小显示的同时,还能防止OOM的出现。

OOM解决方案

OOM解决方案

OOM解决⽅案⼀、什么是OOM OutOfMemory(内存溢出)就是内存⽤完了,意思就是说,当JVM因为没有⾜够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error(注:⾮exception,因为这个问题已经严重到不⾜以被应⽤处理)。

PS.⼀个线程OOM,进程⾥其他线程还能运⾏吗?⼀个线程溢出后,进程⾥的其他线程还能照常运⾏,当⼀个线程抛出OOM异常后,它所占据的内存资源会全部被释放掉,从⽽不会影响其他线程的运⾏。

⼆、OOM产⽣原因1. 分配的少了:⽐如虚拟机本⾝可使⽤的内存(⼀般通过启动时的VM参数指定)太少。

2. 应⽤⽤的太多,并且⽤完没释放,浪费了。

此时就会造成内存泄露或者内存溢出。

三、OOM类型 1.永久区溢出:ng.OutOfMemoryError: PermGen space这⼀部分⽤于存放Class和Meta的信息,Class在被 Load的时候被放⼊PermGen space区域(包括常量池: 静态变量),它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运⾏期对PermGen space进⾏清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。

这种错误常见在web服务器对JSP进⾏pre compile的时候。

可以通过设置jvm启动参数来解决:-XX:MaxPermSize=256m 2. 堆溢出 ng.OutOfMemoryError: Java heap space 这部分⽤于存放类的实例。

被缓存的实例(Cache)对象,⼤的map,list引⽤⼤的对象等等,都会保存于此,过期引⽤可能会导致堆溢出。

堆内存会在jvm启动时⾃动设置,初始值 -Xms为物理内存的1/64,最⼤值-Xmx为1/4;可以通过参数-Xmn、-Xms、-Xmx设置,⼀般-Xms和-Xmx不超过80%,-Xmn为-Xmx的1/4; 3.栈溢出: Exception in thread "main" ng.StackOverflowError 这部分⽤于存放局部变量、⽅法栈帧信息。

Android加载大图片OOM异常解决

Android加载大图片OOM异常解决

Android加载大图片OOM异常解决项目用到加载大图片,app老是出现OOM异常,总结了几点经验,供参考。

1、手动干涉dalvik的堆内存处理效率:1private final static float TARGET_HEAP_UTILIZATION = 0.75f;2//for same activity3public void onCreate()4 {5…………6VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 7…………8 }2、手动指定Android堆大小:1private final static int CWJ_HEAP_SIZE = 6* 1024* 1024 ;2//for same activity3public void onCreate()4 {5…………6 VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。

当然对于内存吃紧来说还可以通过手动干涉GC去处理7…………8 }3、手动指定回收内存,指定gc:1if(bitmap!=null && !bitmap.isRecycled())2 {3 bitmap.recycle();4 System.gc();5 }4、图片必须进行缩放,不然多半会出OOM:1/**2 * @param url3 * 图片的url4 * @param sc5 * ,显示的像素大小6 * @return返回指定RUL的缩略图7 *8 * @author jevan 2012-7-39 *10*/11public static Bitmap loadImageFromUrl(String url, int sc)12 {1314 URL m;15 InputStream i = null;16 BufferedInputStream bis = null;17 ByteArrayOutputStream out = null;1819if (url == null)20return null;21try22 {23 m = new URL(url);24 i = (InputStream) m.getContent();25 bis = new BufferedInputStream(i, 1024 * 4);26 out = new ByteArrayOutputStream();27int len = 0;2829while ((len = bis.read(isBuffer)) != -1)30 {31 out.write(isBuffer, 0, len);32 }33 out.close();34 bis.close();35 } catch (MalformedURLException e1)36 {37 e1.printStackTrace();38return null;39 } catch (IOException e)40 {41 e.printStackTrace();42 }43if (out == null)44return null;45byte[] data = out.toByteArray();46 BitmapFactory.Options options = new BitmapFactory.Options();47 options.inJustDecodeBounds = true;48 BitmapFactory.decodeByteArray(data, 0, data.length, options);49 options.inJustDecodeBounds = false;50int be = (int) (options.outHeight / (float) sc);51if (be <= 0)52 {53 be = 1;54 } else if (be > 3)55 {56 be = 3;57 }58 options.inSampleSize = be;59 Bitmap bmp =null;60try61 {62 bmp = BitmapFactory.decodeByteArray(data, 0, data.length, options); //返回缩略图63 } catch (OutOfMemoryError e)64 {65// TODO: handle exception66 MainActivity.print("Tile Loader (241) Out Of Memory Error " +e.getLocalizedMessage());6768 System.gc();69 bmp =null;70 }71return bmp;72 }把上面几条全部用上,OOM的异常基本上能完全避免!!!以下内容为转载,收藏。

大图片所引起的内存问题(oom)

大图片所引起的内存问题(oom)

大图片所引起的内存问题(oom):在我们android开发中,一个应用使用的内存大小是有限制的.在应用中,如果大量的使用bitmap就很可能导致内存溢出的问题。

比如我在曾经的一个项目中遇到的问题:要使用Gallery来显示多张不同的图片,在给Gallery的每个Item设置图片的时候,想到Bitmap如果不手动的recycle,系统是不会回收它所在的资源的,因为android为了提高效率,bitmap真正的位图数据是在ndk中用C写的,所以就直接使用setImageResource(iconResId),但是部分配置较低的设备上还是会出现oom的错误。

先来分析我遇到的这个问题,在setImageResource中,是根据iconResId得到drawable,然后再将drawable显示在view中。

我们知道,android对于直接通过资源id 载入的资源做了缓存cache,这样下次再需要资源时直接从缓存中得到即可,在Gallery 中用到了多个大图片,每个图片都会进行缓存,即使在Gallery中该view被回收了。

就是这个地方导致了内存溢出。

对于内存溢出的问题,我一般会从五个方面进行入手:一是在内存引用上做些处理,比如说使用软引用,强化引用,弱引用二是可以在内存中加载图片的时候直接在内存中做处理,比如:边界的压缩三是动态的回收内存四是优化Dalvik虚拟机的堆内存的分配五是自定义堆内存大小而对于前面我们找到的问题,我们对第一个和第二个解决办法进行整合就能够解决这个问题,(写代码):private static LinkedHashMap<String, Bitmap> hardManager;private static ConcurrentHashMap<String, SoftReference<Bitmap>> softManager;设置上面两个变量,分别保存包名到Bitmap的强引用的映射和软引用的映射。

android,oom解决方案

android,oom解决方案

android,oom解决方案篇一:android listview oom的一个解决方式android listview 加载大量高清图片不OOM方式第一声明,我不是大神是菜鸟。

可是感觉仍是写一下吧,因为oom太让人恼火了。

网上很多大神提出了一些解决方案,软引用,缓存等等,确实一些方案挺好的,我在那个地址说的方案比较简单,关于菜鸟而言。

可是,关于想写出好点儿的或乃至是能用的程序的菜鸟而言,仍是需要解决的啊。

我碰到的问题确实是listview加载高清大图,图可能720p左右的差不多宽度要全屏了。

开始的时候,一打开程序确实是占用内存四五十兆左右,,加载几张图片就挂了,然后,折腾来折腾去,,发觉,之所之内存占用这么大,只是因为我在登岸界面用了张1080p的壁纸!删掉以后吧背景换成shape,内存占用直接下降到13左右,太棒了。

今天一下午折腾的。

本来我用的是smartimageview 那个开源视图组件,在adapter里面bitmap decode file,结果加载不了几张图,于是,后来,我用里面的setimageview (url),想着可能在里面做过缓存处置吧,然后看看里面他的实现,果然有,于是换成了url来设置imageview。

好很多。

最后做了个测试,200张图,分辨率都很高,很多720p 左右(电话截图的),也有小的,还有几张电话相机照的1300万像素的照片,200张匀速下滑,看内存始终占用在48兆左右,快速下滑一两下没事,持续快速下滑,仍是oom,把largeheap开启以后,观看到持续快速下滑内存占用最高上升到125兆左右。

固然,正常情形下,不许诺这么操作的,待会儿把下拉改成自动下拉,下拉到尾部自动加载5张左右的图片,再结合效劳器端的图片紧缩,能把内存操纵到三四十兆左右。

之因此该效劳器段,是因为此刻能力差,把smartimageview 改坏了也不行。

上传图片的时候在效劳器端紧缩比较方便,一样也节省效劳器空间。

如何进行Android应用的系统优化和内核调试

如何进行Android应用的系统优化和内核调试

Android作为目前全球使用最广泛的移动操作系统之一,拥有庞大的用户群体和应用市场。

然而,随着Android应用的日益增多和功能的不断扩展,系统优化和内核调试逐渐成为开发者们所关注的焦点。

本文将探讨如何进行Android应用的系统优化和内核调试,以提升应用的性能和稳定性。

一、优化内存管理Android系统在资源管理方面相对较好,但是应用中往往存在大量的内存泄漏和占用过多的内存资源的问题。

为了优化内存管理,开发者可以做以下几点调整:1. 合理释放资源:及时释放不再使用的对象或资源,避免造成内存泄漏,可以通过调用相应的函数或使用垃圾回收机制来实现。

2. 使用轻量级数据结构:在实现数据结构时,尽量选择轻量级的数据结构,减少内存消耗。

例如,使用SparseArray代替HashMap,可以节省内存空间。

3. 合理管理线程:合理规划线程的数量和生命周期,避免线程过多或过少造成的系统资源浪费或响应速度下降。

二、优化应用启动速度应用的启动速度直接影响用户体验和满意度。

以下是一些提升应用启动速度的方法:1. 延迟加载:将应用中的一部分功能或资源延迟加载,等到用户需要时再加载。

这样可以减少启动时的负荷,提升启动速度。

2. 使用缓存:对于一些常用的数据或资源,可以使用缓存机制,避免每次启动时都需要重新加载的问题。

3. 避免主线程阻塞:将一些耗时操作放到子线程中执行,避免阻塞主线程,提升应用的响应速度。

三、优化网络请求移动应用中大量使用网络请求来获取数据,因此优化网络请求对于提升应用的性能和用户体验至关重要。

以下是一些优化网络请求的方法:1. 减少请求次数:将多个小的请求合并为一个大的请求,减少网络通信的次数,可以提高网络请求的效率。

2. 使用缓存:对于一些不经常更新的数据,可以使用缓存来避免每次请求都访问服务器,提升数据加载速度。

3. 利用压缩技术:对于一些数据量较大的请求,可以使用数据压缩技术来减小数据传输的大小,提高网络请求速度。

OOM异常的发生原因

OOM异常的发生原因

OOM异常的发⽣原因⼀,jvm内存区域1,程序计数器⼀块很⼩的内存空间,作⽤是当前线程所执⾏的字节码的⾏号指⽰器。

2,java栈与程序计数器⼀样,java栈(虚拟机栈)也是线程私有的,其⽣命周期与线程相同。

通常存放基本数据类型,对象引⽤(⼀个指向对象起始地址的引⽤指针或⼀个代表对象的句柄),reeturnAddress类型(指向⼀条字节码指令的地址)栈区域有两种异常类型:如果线程请求的栈深度⼤于虚拟机所允许的深度,将抛StrackOverflowError异常;如果虚拟机栈可以动态扩展(⼤部分虚拟机都可动态扩展),当扩展时⽆法申请到⾜够的内存时会抛出OutOfMemoryError异常。

3,本地⽅法栈与虚拟机栈作⽤很相似,区别是虚拟机栈为虚拟机执⾏java⽅法服务,⽽本地⽅法栈则是为虚拟机⽤到的Native⽅法服务。

和虚拟机栈⼀样可能抛出StackOverflowError和OutOfMemoryError异常。

4,java堆java Heap是jvm所管理的内存中最⼤的区域。

JavaHeap是被所有线程共享的⼀块内存区域,在虚拟机启动时创建。

主要存放对象实例。

JavaHeap是垃圾收集器管理的主要区域,其可细分为新⽣代和⽼年代。

如果在堆中没有内存完成实例分配,并且也⽆法再扩展时,会抛出OutOfMemoryError异常。

5,⽅法区与javaHeap⼀样是各个线程共享的内存区域,⽤于存放已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。

当⽅法区⽆法满⾜内存分配的需求时,将抛出OutOfMemoryError异常。

⽅法同时包含常听说的运⾏时常量池,⽤于存放编译期⽣成的各种字⾯量和符号引⽤。

6,直接内存直接内存并不是虚拟机运⾏时数据区的⼀部分,也不是java虚拟机规范中定义的内存区域,是jvm外部的内存区域,这部分区域也可能导致OutOfMemoryError异常。

⼆,jvm参数-Xss(StackSpace)栈空间-Xms ,-Xmx(heap memory space)堆空间:Heap是⼤家最为熟悉的区域,他是jvm⽤来存储对象实例的区域,Heap在32位的系统中最⼤为2G,其⼤⼩通过-Xms和-Xmx来控制,-Xms为jvm启动时申请的最⼩Heap内存,默认为物理内存的1/64,但⼩于1G,-Xmx为jvm可申请的最⼤的Heap内存,默认为物理内存的1/4,⼀般也⼩于1G,默认当空余堆内存⼩于40%时,jvm会最⼤Heap的⼤⼩到-Xmx指定⼤⼩,可通过-XX:MinHeapFreeRatio来指定这个⽐例,当空余堆内存⼤于70%时,JVM会将Heap的⼤⼩往-Xms指定的⼤⼩调整,可通过-XX:MaxHeapFreeRatio来指定这个⽐例,但通常为了避免频繁调整HeapSize的⼤⼩,将-Xms和-Xmx的值设为相同。

Probe:Android线上OOM问题定位组件 - 技术团队

Probe:Android线上OOM问题定位组件 - 技术团队

PA R T. 0 3
线程数超出限制
线程数超出限制的原因
1. 线程数超出限制是OOM的一种表现。 2. Probe会获取相关信息进行分析。 3. 虚拟内存、线程数量、线程信息及系统线程数限制都会被考虑。 4. 定位问题并进行修复的方法包括直接搜索代码和通过堆栈信息辅助。
线程信息示例
1. 'crowdSource msg'线程被大量重复创建。 2. 问题快速定位 example。 3. 使用堆栈信息辅助定位。 4. 推荐统一使用线程池。 5. 避免线程数溢出问题。
OOM原因分析
1. OOM定义:内存不足导致程序崩溃。 2. 常见原因:内存分配不当、对象引用错误、递归调用过深等。 3. 分析方法:对比内存使用情况、跟踪程序执行过程、检查代码逻辑。 4. 解决策略:优化代码、调整内存分配、校验数据结构等。
堆内存分配失败的原因及解决策略
1. 堆内存分配失败原因:内存不足、内存泄漏、非法操作等。 2. 解决策略:增加外存、优化代码、使用对象池、谨慎使用new关键字 等。 3. 预防措施:合理规划内存需求、避免创建大量无用对象、及时释放不 再使用的对象等。
Байду номын сангаас
创建线程失败的原因及解决策略
1. 创建线程失败原因:线程名重复、线程池已满、系统资源不足等。 2. 解决策略:使用线程名别名、调整线程池大小、合理分配系统资源等 。
堆内存不足
1. OOM问题常见类型 2. 堆内存不足导致 3. 堆栈信息难以定位问题
Java内存快照文件
1. Java内存快照文件(HPROF文件) 2. 帮助定位OOM问题 3. 需要 dump 函数获取 4. 可能无法得到完整的内存快照文件
Android线上OOM问题定位组件

应对Android测试中的各种异常情况

应对Android测试中的各种异常情况

应对Android测试中的各种异常情况在Android测试中,经常会面临各种各样的异常情况。

这些异常情况可能会导致应用程序崩溃、功能失效或者测试结果不准确。

为了保证测试的完整性和准确性,我们需要有一套有效的应对措施来处理这些异常情况。

以下是我总结的一些应对Android测试中各种异常情况的方法:一、OOM(Out of Memory)异常OOM异常在Android开发和测试中是非常常见的。

它通常发生在内存资源不足时,导致应用程序无法继续正常执行。

为了应对这种异常情况,我们可以采取以下措施:1. 检查内存泄露:使用工具(如LeakCanary)来检测应用程序中的内存泄露问题,及时修复这些问题。

2. 内存优化:尽量减少不必要的内存占用,如使用适当的数据结构、避免加载大量的图片资源等。

二、ANR(Application Not Responding)异常ANR异常是指当应用程序无响应超过一定时间(通常为5秒),系统会弹出ANR对话框,提示用户应用程序停止响应。

为了避免ANR异常的发生,我们可以采取以下措施:1. 尽量减少后台线程的运行时间:避免在主线程内执行耗时操作,通过使用异步任务或者后台线程来执行这些操作。

2. 优化UI线程的响应时间:减少UI线程的负载,避免进行耗时的操作,如加载大量图片或者进行复杂的计算等。

三、网络异常网络异常可能会导致应用程序无法正常访问网络资源,或者请求超时等问题。

为了应对这种异常情况,我们可以采取以下措施:1. 检查网络连接状态:在进行网络请求前,先检查网络连接状态,如果没有网络连接,则给出适当的提示信息给用户。

2. 添加超时机制:在进行网络请求时,设置适当的超时时间,如果请求超过了指定的时间还没有返回结果,可以进行重试或者给出相关提示信息。

四、设备兼容性问题Android平台的设备种类繁多,设备的硬件和系统版本也各不相同,因此在测试过程中可能会出现设备兼容性问题。

为了解决这种异常情况,我们可以采取以下措施:1. 多设备测试:在进行测试时,尽量涵盖不同类型的Android设备,包括不同的品牌、型号和系统版本。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
将在工具篇详细介绍。
发生OOM如何定位
• 内存分析工具MAT。
将在工具篇详细介绍。
如何解决OOM问题
• 创建对象时,谨慎对待其生命周期,尤其是静态对象。对象
的生命周期应与其上下文周期一致;
场景1:全局静态对象若需要调用context对象,应取Application Context,而不 应使用Activity context,以避免Activity对象无法被回收
OOM产生原因
关于GC(Android 2.3之后的版本):
• • Cocurrent,GC线程与其他线程是并发执行; Partial collection,一次可能只回收一部分垃圾;


一次垃圾回收造成的程序中止时间通常小于5s;
几种GC类型:
GC_CONCURRENT GC_FOR_MALLOC GC_EXTERNAL_ALLOC GC_HPROF_DUMP_HEAP GC_EXPLICIT
• 分析Logcat日志中dump的memory信息; • Memory相关术语: ( VSS >= RSS >= PSS >= USS )
VSS (Virtual Set Size) RSS (Resident Set Size)
进程能访问的所有内存空间大小,包含了一些没有驻留在 RAM的内存,比如mallocs已分配但尚未写入 实际占用的内存,包含所有该进程使用的共享库所占用的 内存总大小 比如3个进程共享一个库,则每个进程会计算该库占用的 1/3内存大小。很重要的参考量,系统所有进程的PSS总和 即为系统占用内存的总和。
上限,超过这个上限就会出现OOM问题。
OOM产生原因
Dalvik内存相关知识: • • Dalvik内存大体上分为Java Object Heap、Bitmap Memory和Native Heap三 种; Java Object Heap的大小,从dalvik.vm.heapstartsize读取缺省最小值,从 dalvik.vm.heapsize读取缺省最大值,这个最大值就是Android应用进程能够 使用的最大内存,超过了这个值就会造成OOM; • 在HoneyComb之后的版本,Bitmap Memory直接在Java Object Heap中分 配,可以受GC的管理。之前的版本是在Native Heap中分配的,但是大小是 计入Java Object Heap的使用大小之内的; • Native Heap是Native code(c/c++)使用的内存,不受Java Object Heap的大 小限制。
• 频繁创建对象;
• 资源泄漏;
• 加载数据量太大导致内存占用过多。
发生OOM如何定位
• 分析Logcat日志中的stack trace dump;
• DDMS内存监测工具Heap; • 内存分析工具MAT(Memory Analyzer Tool)
发生OOM如何定位
• 分析Logcat日志中dump的OOM stack trace;
场景2:receiver的register/unregister应成对出现,在退出或暂停组件时应注销
• 在频繁调用新对象的情况下,应尽量复用已有的缓存对象
场景1:实现ListView的Adapter类时,对于getView方法,应尽量使用传入的缓 存对象convertView 场景2:使用Handler进行消息传递时,应调用Handler.obtainMessage方法获取 缓存的Message对象
如何解决OOM问题
• 避免资源泄漏;
场景:如数据库cursor,文件描述符等系统资源,在处理完毕后都应 close。
• 加载大块数据时,使用soft ref或者weak ref,并进行缓存管 理;
场景:加载大量图片时,应使用soft ref,并进行队列缓存管理。
• 加载Bitmap资源时,使用sample处理,并在使用后调用 recycle方法;
PSS (Proportional Set Size) 实际占用的内存,包含按比例分配共享库所占用的内存,
USS (Unique Set Size)
进程独自占用的物理内存,运行一个特定进程所需的真正 成本,当进程被杀死时,USS即为系统回收的内存值。
发生OOM如何定位
• DDMS内存监测工具Heap。
Android系统优化系列之二 OOM篇
Overview
• 什么是OOM
• OOM产生原因
• 发生OOM如何定位
• 如何解决OOM问题
• 参考资料
什么是OOM
• OOM是“Out of memory error”的缩写,即“内
存溢出错误”;
• Anroid系统中,每个Process都有一个可使用内存
如何解决OOM问题
• 对于超出组件周期的处理应考虑换用安全合理的解决方案;
场景:Activity调用AsyncTask做异步处理,在退出Activity时,应取消 AsyncTask的异步线程处理,若逻辑上需要继续执行,安全的做法是采 用后台Service的处理方案。
参考资料
• /blog/1956059 • /blog/1956638 • /luoshengyang/article/details/8 852432
避免Heap内存满而执行的回收 应用分配内存不足,需要更多内存进行的回收 为external分配的内存执行的回收,如Bitmap 做HPROF操作创建HPROF文件的时候执行的 程序显式调用了System.gc()引起的回收
OOM产生原因
常见原因
• 对象被长时间强引用,导致无法被GC回收,而造
成内存泄漏;
相关文档
最新文档