About ANR and OOM

来源:互联网 发布:amazon跟卖软件 编辑:程序博客网 时间:2024/06/04 18:08

1. ANR

    1.1 什么是ANR? ANR(Application Not Responding)

        在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:ApplicationNotResponding)对话框。用户可以选择“等待”而让程序继续运行,也可以选择“强制关闭”。所以一个流畅的合理的应用程序中不能出现anr,而让用户每次都要处理这个对话框。

          默认情况下,在android中Activity的最长执行时间是5秒,BroadcastReceiver的最长执行时间则是10秒 (厂商可以定制 这个时间)


    1.2 产生ANR的原因?

        1.在5秒内没有响应输入的事件。
        2.BroadcastReceiver在制定时间内完成

        具体点的原因: 1) IO操作耗时 。  2)数据库操作复杂耗时。 3)主线程  非主线程 产生死锁等待。 4)网络加载/图片操作耗时。  5)硬件操作耗时。

                                     1) service binder 数量达到上限。 2)Service忙导致超时无响应。


    1.3 ANR是哪里报出来的?

        ActivityManagerService 管理每个应用程序是否发生了ANR  。按照ANR发生的不同类型,细致一点的说:

        1)KeyDispatchTimeout :每次dispatch 触摸事件的时候都会检查当前接收事件的app是否 ready 去处理下一个事件,判断的过程中会检查是否发生了ANR。检查的办法是ActivityManagerService对比上次记录的该pid的处理时间和当前时间的差值,是否大于系统规定的ANR超时时间。

        2)BroadcastTimeout:ActivityManagerService 管理着几个broadcastQueue,这些broadcastQueue 管理者不同类型的broadcast。每个broadcast发送给注册的对象都有一个时间限制,BroadCastQueue会记录每次发送的开始时间以及结束时间,如果超过了ANR规定时间就会发生ANR。通过调用AMS中的AppNotResponding来弹出系统弹窗。

        3)ServiceTimeout:与KeyDispatchTimeout 类似。(没有具体的看)

    1.4 如何尽力避免ANR?

        1)运行在主线程里的任何方法都尽可能少做事情。特别是,Activity应该在它的关键生命周期方法(如onCreate()和onResume())里尽可能少的去做创建操作。(可以采用重新开启子线程的方式,然后使用Handler+Message的方式做一些操作,比如更新主线程中的ui等)

        2)应用程序应该避免在BroadcastReceiver里做耗时的操作或计算。但不再是在子线程里做这些任务(因为BroadcastReceiver的生命周期短),替代的是,如果响应Intent ,应用程序应该启动一个Service。

        3)避免在IntentReceiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广播时需要向用户展示什么,你应该使用Notification Manager来实现。

    1.5 出现ANR如何解决。

        解决ANR 主要通过 报错log和Trace文件分析解决。 从产生的原因入手。 具体方法可以参考一下: http://www.cnblogs.com/purediy/p/3225060.html


2. Crash

    Crash 包括很多情况,在进行系统debug的时候很容易区分。 例如JAVA层的Fatal 错误, 在log中会明确的打印出具体原因, 是数组越界/未初始化变量/空指针等。又比如C/C++层的错误,会打印出相应的信息,我们可以通过addr2line  来进行debug。 应用层的crash 是我们常说的FC。  system service 的crash 会导致 系统不能启动/重启等问题。

http://blog.csdn.net/god2469/article/details/9713395   (常见的SIG错误以及含义)


3. OOM

    OOM是指Out Of Memory。每个android应用单独使用一个Dalvik虚拟机,每个虚拟机使用的堆内存是有限的,超过了限制就会引发oom错误。造成OOM几乎都是自己的代码结构导致的不良。常见的原因:

   1)不恰当的使用static关键字。 尽量不要使用static保存对象。

   2)内部类对Activity的引用。 内部类对象如果引用Activity对象,同时有很长的声明周期的话会导致 Activity对象释放不及时。

   3)Bitmap使用。 大量的bitmap会导致 程序包和运行时的内存消耗变大。

   4)游标cursor的使用。 Cursor 对象用完应该及时关闭

   5)其他的内容。 我个人不能列举所有的情况。其他的是我暂时没有想到的 欢迎指教

文章中有一些引用的地方。不算原创。

1 0
原创粉丝点击