本文共 6277 字,大约阅读时间需要 20 分钟。
龙哥发现,省电进程内存占用率高
这里可以使用Android Studio Memory Usage 查看
Memory Usage 360,408K: Persistent 37,159K: com.android.lava.powersave (pid 1873 / activities)
adb shell dumpsys meminfo packagename -d
重点关注 Views 和 Activities 变化,如果有差异,则说明存在内存泄露。
Objects Views: 293 ViewRootImpl: 2 AppContexts: 9 Activities: 5 Assets: 4 AssetManagers: 2 Local Binders: 32 Proxy Binders: 27 Parcel memory: 3 Parcel count: 12 Death Recipients: 0 OpenSSL Sockets: 0 WebViews: 0
这里我不断进入我的应用界面,发现 Activities 的数量和我进入界面的次数保持一致,且是递增的,这里内存泄露了
adb shell dumpsys meminfo com.android.lava.powersave -dC:\Users\fadi.su>adb shell dumpsys meminfo com.android.lava.powersave -dApplications Memory Usage (in Kilobytes):Uptime: 59740597 Realtime: 90131515** MEMINFO in pid 1873 [com.android.lava.powersave] ** Pss Private Private SwapPss Heap Heap Heap Total Dirty Clean Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ ------ Native Heap 8111 7996 92 0 18432 12289 6142 Dalvik Heap 2526 2444 48 0 7129 4278 2851 Dalvik Other 518 492 24 20 Stack 52 52 0 0 Ashmem 82 4 0 0 Other dev 8 4 4 0 .so mmap 5238 156 428 58 .apk mmap 398 0 20 0 .ttf mmap 40 0 0 0 .dex mmap 1268 0 1268 4 .oat mmap 4790 0 648 0 .art mmap 1501 612 360 69 Other mmap 2162 4 932 0 EGL mtrack 3666 3666 0 0 GL mtrack 7137 7137 0 0 Unknown 594 496 92 70 TOTAL 38312 23063 3916 221 25561 16567 8993 App Summary Pss(KB) ------ Java Heap: 3416 Native Heap: 7996 Code: 2520 Stack: 52 Graphics: 10803 Private Other: 2192 System: 11333 TOTAL: 38312 TOTAL SWAP PSS: 221 Objects Views: 293 ViewRootImpl: 2 AppContexts: 9 Activities: 5 Assets: 4 AssetManagers: 2 Local Binders: 32 Proxy Binders: 27 Parcel memory: 3 Parcel count: 12 Death Recipients: 0 OpenSSL Sockets: 0 WebViews: 0 SQL MEMORY_USED: 613 PAGECACHE_OVERFLOW: 258 MALLOC_SIZE: 62 DATABASES pgsz dbsz Lookaside(b) cache Dbname 4 24 57 73/51/10 /data/user/0/com.android.lava.powersave/databases/app_usage.db 4 72 54 32/48/7 /data/user/0/com.android.lava.powersave/databases/lavapowersave.db 4 100 43 406/48/7 /data/user/0/com.android.lava.powersave/databases/night_mode.dbC:\Users\fadi.su>
非静态内部类导致的内存泄露,比如Handler,解决方法是将内部类写成静态内部类,在静态内部类中使用软引用/弱引用持有外部类的实例,eg
private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_SWITCH: key_power_save_mode.setChecked(PowerSaveManagerUtil.isLavaPowerSaveMode(LavaPowerSaveManager.this)); key_super_power_save_mode.setChecked(PowerSaveManagerUtil.isLavaSuperPowerSaveMode(LavaPowerSaveManager.this)); case MSG_UPDATE_CLICKABLE: key_power_save_mode.setEnabled(true); break; } } };
@Override protected void initValues() { mHandler = new MyHandler(this); } private static class MyHandler extends Handler{ WeakReferencemActivity; public MyHandler(LavaPowerSaveManager activity) { mActivity = new WeakReference (activity); } @Override public void handleMessage(Message msg) { LavaPowerSaveManager activity = mActivity.get(); switch (msg.what) { case MSG_UPDATE_SWITCH: activity.key_power_save_mode.setChecked(PowerSaveManagerUtil.isLavaPowerSaveMode(activity)); activity.key_super_power_save_mode.setChecked(PowerSaveManagerUtil.isLavaSuperPowerSaveMode(activity)); case MSG_UPDATE_CLICKABLE: activity.key_power_save_mode.setEnabled(true); break; } } }
不断进入界面,查看 Activities 的数量变化,并且不在是自增,且随着静置的时间越长,Activities 数值越小。
Objects Views: 125 ViewRootImpl: 1 AppContexts: 7 Activities: 2 Assets: 5 AssetManagers: 3 Local Binders: 32 Proxy Binders: 26 Parcel memory: 3 Parcel count: 14 Death Recipients: 0 OpenSSL Sockets: 0 Objects Views: 125 ViewRootImpl: 1 AppContexts: 7 Activities: 2 Assets: 5 AssetManagers: 3 Local Binders: 31 Proxy Binders: 25 Parcel memory: 3 Parcel count: 14 Death Recipients: 0 OpenSSL Sockets: 0 WebViews: 0Objects Views: 56 ViewRootImpl: 1 AppContexts: 6 Activities: 1 Assets: 5 AssetManagers: 3 Local Binders: 28 Proxy Binders: 23 Parcel memory: 3 Parcel count: 14 Death Recipients: 0 OpenSSL Sockets: 0 WebViews: 0
这里进行省电模块的排查,尤其是对非静态内部类导致的内存泄露进行优化。