android中systemUI是作为一个设置壁纸的服务存在的.以前项目中,对systemUI做了延迟启动的优化,可以把内存从25M左右降到8M左右,可是最近一个项目用了同样的方法(延迟启动),内存却仍然占用25M.
1. procrank | busybox grep systemui
结果: 11212 63936K 44144K 27010K 25788K com.android.systemui # USS 占用25M
2. dumpsys meminfo 11212
结果:
Applications Memory Usage (kB):
Uptime: 8264904 Realtime: 8264904
** MEMINFO in pid 11212 [com.android.systemui] **
Shared Private Heap Heap Heap
Pss Dirty Dirty Size Alloc Free
------ ------ ------ ------ ------ ------
Native 0 8 0 8580 1650 209
Dalvik 24528 5700 24380 25992 25734 258
Cursor 0 0 0
Ashmem 0 0 0
Other dev 96 56 0
.so mmap 1203 2444 496
.jar mmap 0 0 0
.apk mmap 46 0 0
.ttf mmap 0 0 0
.dex mmap 253 0 0
Other mmap 28 16 28
Unknown 817 504 812
TOTAL 26971 8728 25716 34572 27384 467
3. showmap 11212
结果
virtual shared shared private private
size RSS PSS clean dirty clean dirty # object
-------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
*
*
4096 60 60 0 0 0 60 1 /dev/ashmem/dalvik-bitmap-2 (deleted)
2052 212 212 0 0 0 212 1 /dev/ashmem/dalvik-card-table (deleted)
262144 26596 24455 0 2196 0 24400 3 /dev/ashmem/dalvik-heap (deleted)
1024 88 88 0 0 0 88 1 /dev/ashmem/dalvik-jit-code-cache (deleted
*
*
-------- -------- -------- -------- -------- -------- -------- ---- ------------------------------
4. 分析到这里,还是没有什么卵用.分析以下system ui的启动log吧,
发现:
4 D/Zygote ( 9704): Process 10352 terminated by signal (15)
75 I/ActivityManager(10239): Start proc com.android.systemui for restart com.android.systemui: pid=11212 uid=10038 gids={50038, 1028, 1015, 1023, 3002, 3001}
76 D/ActivityManager(10239): test resumeTopActivty
77 D/ActivityManager(10239): resumeTopActivty
78 D/ActivityManager(10239): set persist.sys.bootformui true
79 I/ (11212): jpeg hw mutex s_index = 319
80 I/ (11212): [MSOS_PRINT][003274] ~!~mappd sharemem @^A
81 I/ (11212): [MSOS_PRINT][000640] pthread_mutex_init
82 I/ (11212): [MSOS_PRINT][000642] CHIP_InitISR
83 D/ (11212): [skia jpeg]: readbuf addr:0x1b14a000, size: 0x100000
84 D/ (11212): write buff addr:0x1b34a000, size: 0x1500000
85 D/ (11212): internal buff addr:0x1b24a000, size: 0x100000
86 D/skia (11212): ---- fAsset->read(157360) returned 0
87 E/ (11212): jpeg goto fail 0, s16JpegDecoderErrCode = -233
88 I/ (11212): [MPlayerLib]:Decode jpeg fail, s16JpegDecoderErrCode = -233
89 E/ (11212): go sw decode!
90 D/dalvikvm(11212): GC_FOR_ALLOC freed 59K, 11% free 2318K/2592K, paused 16ms, total 16ms
91 I/dalvikvm-heap(11212): Grow heap (frag case) to 11.257MB for 9216016-byte allocation
92 D/dalvikvm(11212): GC_FOR_ALLOC freed 1K, 3% free 11317K/11596K, paused 11ms, total 11ms
93 D/dalvikvm(11212): GC_CONCURRENT freed 0K, 3% free 11317K/11596K, paused 3ms+2ms, total 16ms
94 E/bt_userial_vendor(10759): count = 39
95 E/bt_userial_vendor(10759): /dev/btusb0 file exist
96 E/bt_userial_vendor(10759): /dev/btusb0's size is 0 bytes
97 E/bt_userial_vendor(10759): /dev/btusb0's t_blksize is 4096 bytes
98 E/bt_userial_vendor(10759): /dev/btusb0's blocks is 0 blocks
99 D/dalvikvm(11212): GC_FOR_ALLOC freed <1K, 3% free 11317K/11596K, paused 11ms, total 11ms
100 I/dalvikvm-heap(11212): Grow heap (frag case) to 25.319MB for 14745616-byte allocation
看到了吗, 原因就是因为jpeg硬解码失败,使用了软解码, 导致内存使用暴增,而其他平台是硬解码成功的,所以内存占用小.
但是这还是没用,因为硬件厂商基本上不会再为这个项目维护了,让他们去改希望也比较渺茫了.
5.还是不死心,用ddms 分析一下吧.上图:
占用27M, 但是当我点了一下GC后, 神奇的事情发生了,上图:
美柚看错, HEAP占用变成了2M, 我们再用 procrank | grep systemui 看下:
结果: 1883 40608K 20816K 3700K 2484K com.android.systemui
的的确确是变小了. 看来system ui刚启动的时候图片操作占用了内存,但是过后变成了垃圾内存, 我们只要用gc对其一下垃圾回收便能够释放内存,缩小差不多20M的内存占用.
那么我目前的想法,我不想修改systemui 的源码, 既然ddms能够发出gc的命令,那么我一定可以找到类似的方法 去让system ui做gc的操作. 功夫不负有心人,
我终于找到了一条命令: 她就是 : kill -10 ${PID} ,
感兴趣的同学可以看下虚拟机的代码, 虚拟机接收到USR1 的信号时,会做垃圾回收处理, USER1的信号就是10.
下面 是我写的一个简单shell,放到开机时时启动, 当systemui的uss 内存占用大于20M时, 就发一个gc命令.
#!/system/bin/sh THRESH_HOLD=20000 while true do SYSTEMUI_PID=`procrank 2>&1 | busybox grep systemui | busybox awk '{print $1}'` SYSTEMUI_MEM=`procrank 2>&1 | busybox grep systemui | busybox awk '{print $5}'` SYSTEMUI_MEM=${SYSTEMUI_MEM%%K} #echo ---------- #echo ${SYSTEMUI_PID} #echo ${SYSTEMUI_MEM} #echo ---------- if [ ${SYSTEMUI_MEM} -gt ${THRESH_HOLD} ]; then echo "gc systemui..." kill -10 ${SYSTEMUI_PID} fi sleep 30 done