Android StatckOverFlowError/OutOfMemoryError(OOM),ANR,FC

APP 可能会出现卡顿、OOM、ANR FC 等现象。
> FC:force close出现原因
  force close,意为强行关闭,当前应用程序发生了冲突;NullPointExection(空指针),IndexOutOfBoundsException(角标越界)等等一系列未捕获异常

> ANR:Log分析
android anr traces日志分析方法-http://blog.csdn.net/qwiwuqo/article/details/40111721
 - Android Not Response : 通常是UI线程做耗时操作会导致ANR。
 A。界面操作按钮的点击等待响应时间超过5秒
 B。HandleMessage回调函数执行超过10秒,BroadcasterReciver里的onRecive()方法处理超过10秒
 
 - 常见问题原因:
1. 数据库操作I/O被阻塞,iowait、ContentResolver.query、onPostExecute
2. 在UI线程进行网络数据的读写
3. 内存不足导致block在创建bitmap上
  atdalvik.system.VMRuntime.trackExternalAllocation(NativeMethod);
  atandroid.graphics.Bitmap.createBitmap(Bitmap.java:468);
4. 程序异常退出,uncausedexception      (Fatal)
5. 程序强制关闭,ForceClosed (简称FC)       (Fatal)      
6. 通过搜索ANR定位问题

-- ANR的类型
ANR一般有三种类型:
1:KeyDispatchTimeout(5 seconds) --主要类型
  按键或触摸事件在特定时间内无响应
2:BroadcastTimeout(10 seconds)
  BroadcastReceiver在特定时间内无法处理完成
3:ServiceTimeout(20 seconds) --小概率类型
  Service在特定的时间内无法处理完成

-- 超时时间的计数一般是从按键分发给app开始。超时的原因一般有两种:
(1)当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
(2)当前的事件正在处理,但没有及时完成

-- 从LOG可以看出ANR的类型,CPU的使用情况,如果CPU使用量接近100%,说明当前设备很忙,有可能是CPU饥饿导致了ANR:
 如果CPU使用量很少,说明主线程被BLOCK了;
 如果IOwait很高,说明ANR有可能是主线程在进行I/O操作造成的;
 除了看LOG,解决ANR还得需要trace.txt文件。

> StatckOverFlowError(栈溢出);OutOfMemoryError(内存溢出)
  - 内存溢出与内存泄漏的区别:
  内存溢出(Out of memory):系统会给每个APP分配内存也就是Heap size值,当APP所需要的内存大于了系统分配的内存,就会造成内存溢出;通俗点就是10L桶只能装10L水,但是你却用来装11L的水,那就有1L的水就会溢出;
  内存泄漏(Memory leak):当一个对象不在使用了,本应该被垃圾回收器(JVM)回收,但是这个对象由于被其他正在使用的对象所持有,造成无法被回收的结果,通俗点就是系统把一定的内存值A借给程序,但是系统却收不回完整的A值,那就是内存泄漏
  内存泄漏是造成内存溢出(OOM)的主要原因,因为系统分配给每个程序的内存也就是Heap size的值都是有限的,当内存泄漏到一定值的时候,最终会发生程序所需要的内存值加上泄漏值大于了系统所分配的内存额度,就是触发内存溢出
  内存溢出:会触发Java.lang.OutOfMemoryError,造成程序崩溃;
  内存泄漏:过多的内存泄漏会造成OOM的发送,同样也会造成相关UI的卡顿现象.

-- 代码实现堆溢出、栈溢出、永久代溢出、直接内存溢出- https://blog.csdn.net/JENREY/article/details/80106161
栈内存溢出:程序所要求的栈深度过大。 
堆内存溢出: 分清内存泄露还是内存容量不足。泄露则看对象如何被 GC Root 引用,不足则通过调大-Xms,-Xmx参数。 
永久代溢出:Class对象未被释放,Class对象占用信息过多,有过多的Class对象。 
直接内存溢出:系统哪些地方会使用直接内存。

-- Android OOM案例分析- https://blog.csdn.net/meituantech/article/details/80062521
  模拟复现OOM,为了能够尽量模拟用户发生OOM的场景,需要基本条件基本一致,即用户使用的手机的各种相关参数。
  dump和分析内存都很耗时,效率难以接受。OOM发生后,使用Android Studio自带的Android Monitor dump出HPROF文件,然后使用SDK中的hprof-conv(位于sdk_root/platform-tools)工具转换为标准的Java堆转储文件格式,这样可以使用MAT(Eclipse Memory Analyzer)继续分析。

-- OOM: 
一,压缩图片,主动释放Bitmap的内存(大对象);
二,设计Cache。Runtime.getMaxMemory()
Android性能优化——如何避免OOM总结-http://blog.csdn.net/sinat_15877283/article/details/50776228
  首先是减小对象的内存占用,其次是内存对象的重复利用,然后是避免对象的内存泄露,最后是内存使用策略优化。
  原因:一、加载对象过大 ; 二、相应资源过多,没有来不及释放。
解决这样的问题:
   a:在内存引用上做些处理,常用的有软引用、强化引用、弱引用
   b:在内存中加载图片时直接在内存中做处理,如:边界压缩.
三:动态回收内存
四:优化Dalvik虚拟机的堆内存分配
五:自定义堆内存大小
   a、应该尽量避免static成员变量引用资源耗费过多的实例,比如Context。
   b、Context尽量使用Application Context,因为Application的Context的生命周期比较长,引用它不会出现内存泄露的问题。
   c、使用WeakReference代替强引用。比如可以使用WeakReference<Context> mContextRef;

-- Java反射机制是一个非常强大的功能,在很多大型项目比如Spring, Mybatis中都可以看见反射的身影。通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题。
 35 个 Java 代码性能优化总结- https://coderknock.com/blog/2017/03/10/35%20%E4%B8%AA%20Java%20%E4%BB%A3%E7%A0%81%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E6%80%BB%E7%BB%93.html
内存泄露- http://droidyue.com/blog/2016/11/23/memory-leaks-in-android/
谈谈Java内存管理- http://blog.csdn.net/qq_35101189/article/details/71158247
35 个 Java 代码性能优化总结- http://geek.csdn.net/news/detail/235508

-- java内存泄露
  内存泄露:没有用的对象无法回收的现象就是内存泄露. 如果程序发生了内存泄露,则会带来如下的问题:
1.应用可用的内存减少,增加了堆内存的压力
2.降低了应用的性能,比如会触犯更频繁的GC
3.严重的时候可能会导致内存溢出错误,即OOM Error

-- Java中的对象:
1.当我们使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象
2.创建的对象可以被局部变量,实例变量和类变量引用。
3.通常情况下,类变量持有的对象生命周期最长,实例变量次之,局部变量最短。
4.垃圾回收器回收非存活的对象,并释放对应的内存空间。

-- GC垃圾回收器运行在JVM中.
  通常GC有两种算法:
引用计数:循环引用的问题引用计数算法的垃圾回收器无法解决。主流的JVM很少使用基于这种算法的垃圾回收器实现。
GC根节点遍历:主流的JVM一般都采用这种算法的垃圾回收器实现

-- Android中的内存泄漏场景
Android应用内存泄漏的定位、分析与解决策略-http://geek.csdn.net/news/detail/127226
Android内存泄漏优化总结- http://blog.csdn.net/u014600432/article/details/78157235

使用Activity.getSystemService()使用不当,也会导致内存泄漏;资源未关闭也会造成内存泄漏;
Handler使用不当也可以造成内存泄漏的发生;

延迟的任务也可能导致内存泄漏;

  按照类型划分
长期持有(Activity)Context导致的;
忘记注销监听器或者观察者;
由非静态内部类导致的;

  按照泄漏的程度
长时间泄漏,即泄漏只能等待进程退出才消失;
短时间泄漏,被泄漏的对象后续会被回收掉。

  解决内存泄漏:
手动解除不必要的强引用关系;
使用弱引用或者软引用替换强引用关系;

-- 内存泄漏检测和解决的工具:
Strictmode,严格模式,是Android中的一种检测VM和线程违例的工具。
Android Memory Monitor内置于Android Studio中,用于展示应用内存的使用和释放情况。
LeakCanary是一个检测Java和Android内存泄漏的库.
一个Heap dump就是某一时间点的内存快照.
Shallow Heap 指的是对象自身的占用的内存大小。
Retained Heap,对象x的Retained Set指的是如果对象x被GC移除,可以释放总的对象的集合。
Retained Heap,对象x的Retained Heap指的就是上述x的Retained Set的占用内存大小。

    OOM发生在,当我们尝试进行创建对象,但是堆内存无法通过GC释放足够的空间,堆内存也无法在继续增长,从而完成对象创建请求,所以发生了OOM; OOM发生很有可能是内存泄漏导致;但是并非所有的OOM都是由内存泄漏引起;内存泄漏也并不一定引起OOM;

-- Android性能全面分析与优化方案研究- https://blog.csdn.net/Ch97CKd/article/details/79847070
性能优化工具:
  1、手机开发者选项:调试GPU过度绘制、启用严格模式、显示CPU使用情况、GPU呈现模式分析、显示所有"应用程序无响应"。(小米手机开发开发者选项中名字)
  2、IDE中:Android Studio,比如静态代码检测工具、Memory Monitor、CPU Monitor、NetWork Monitor、GPU Monitor、Layout Inspector、Analyze APK等。
  3、SDK中:sdk\tools,比如DDMS、HierarchyViewer、TraceView等。
  4、第三方工具:MAT、LeakCanary、GT等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值