最近在处理项目的拷机问题,发现在测试24小时内,都是正常的,但是超过24小时后,重启一大片,让人抓狂。

分析了logcat打印,发现重启是因为系统服务已经被watchdog kill掉:

03-06 22:27:49.541   710  1064 W Watchdog: foreground thread stack trace:
03-06 22:27:49.542   710  1064 W Watchdog:     at android.os.MessageQueue.nativePollOnce(Native Method)
03-06 22:27:49.542   710  1064 W Watchdog:     at android.os.MessageQueue.next(MessageQueue.java:323)
03-06 22:27:49.542   710  1064 W Watchdog:     at android.os.Looper.loop(Looper.java:135)
03-06 22:27:49.542   710  1064 W Watchdog:     at android.os.HandlerThread.run(HandlerThread.java:61)
03-06 22:27:49.542   710  1064 W Watchdog:     at com.android.server.ServiceThread.run(ServiceThread.java:46)
03-06 22:27:49.542   710  1064 W Watchdog: *** GOODBYE!

这种情况,就要抓anr的traces.txt来分析:

"AlarmManager" prio=5 tid=26 Runnable
  | group="main" sCount=0 dsCount=0 obj=0x12ea03a0 self=0xeb2a6b00
  | sysTid=755 nice=0 cgrp=default sched=0/0 handle=0xde222930
  | state=R schedstat=( 98972491401001 276479663271 2197759 ) utm=9888269 stm=8980 core=1 HZ=100
  | stack=0xde120000-0xde122000 stackSize=1038KB
  | held mutexes= "mutator lock"(shared held)
  .....
  - locked <0x024448df> (a com.android.server.am.ActivityManagerService)


"main" prio=5 tid=1 Blocked
  | group="main" sCount=1 dsCount=0 obj=0x3426dfa0 self=0xf3934500
  | sysTid=710 nice=-2 cgrp=default sched=0/0 handle=0xf77344c0
  | state=S schedstat=( 7312752856937 488253068832 1803739 ) utm=659213 stm=72062 core=1 HZ=100
  | stack=0xff39d000-0xff39f000 stackSize=8MB
  | held mutexes=
  at com.android.server.am.ActivityManagerService.finishReceiver(ActivityManagerService.java:17259)
  - waiting to lock <0x024448df> (a com.android.server.am.ActivityManagerService) held by thread 26



如上情况,main线程等待lock被tid=26的线程锁定的AcivitiyManagerService变量,一直无法获取到此对象,导致Watchdog超时,系统重启。

可是tid=26的线程状态是Runnable的,并没有等待其它锁,但为什么会造成持锁过久呢?

回到logcat的输出,没有发现明确的问题点。考虑到拷机要测试24小时后才会出现,有一种可能就是出现内在泄漏。这边采用eclipse的DDMS的插件进行分析。

下面是android sdk对这个工具的使用介绍:

Viewing heap usage for a process

DDMS allows you to view how much heap memory a process is using. This information is useful in tracking heap usage at a certain point of time during the execution of your application.

To view heap usage for a process:

  1. In the Devices tab, select the process that you want to see the heap information for.
  2. Click the Update Heap button to enable heap information for the process.
  3. In the Heap tab, click Cause GC to invoke garbage collection, which enables the collection of heap data. When the operation completes, you will see a group of object types and the memory that has been allocated for each type. You can click Cause GC again to refresh the data.
  4. Click on an object type in the list to see a bar graph that shows the number of objects allocated for a particular memory size in bytes.

下图是工具界面:



上面红框显示的#Objects是测试一段时间的数量,而开始前的数量如下:



可以看到#Objects出现了明显的增长。很可能出现了内存泄漏。因此,我们继续根据测试项运行的代码及系统调用,就可以比较容易定位到问题点。



更多相关文章

  1. 【转】【Android游戏开发十五】关于Android(安卓)游戏开发中 OnT
  2. EventBus3.0配置及使用
  3. appium并发测试
  4. 【转】Android(安卓)Audio System
  5. Android线程优先级规定及其设置的具体方法
  6. Android(安卓)性能优化:多线程
  7. 【Android(安卓)消息处理】Handler、Looper、Message 源码浅析
  8. AndroidPN真机环境测试
  9. Android自动化测试解决方案

随机推荐

  1. CDH5 完美手动配置过程改进版
  2. 同样是爬天气,凭什么他能撩到妹?!
  3. position和float属性详解
  4. Hadoop学习笔记之Hadoop伪分布式环境搭建
  5. 类的声明,实例化,静态成员,扩展;trait的用处
  6. 如何溯源挖矿主机
  7. Java基础编程练习6:求100~999之间的水仙花
  8. Java基础编程练习5:求1~100之间的偶数和?
  9. Java基础编程练习4:求一个长整数的各位数
  10. Java基础编程练习3:随机生成20个1~100之间