博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[内存泄露]省电应用的非静态内部类导致的内存泄露
阅读量:4147 次
发布时间:2019-05-25

本文共 6277 字,大约阅读时间需要 20 分钟。

 一、现象

龙哥发现,省电进程内存占用率高

这里可以使用Android Studio Memory Usage 查看

Memory Usage    360,408K: Persistent             37,159K: com.android.lava.powersave (pid 1873 / activities)

1.查看方法

Memory Usage

 二、分析

1.查看应用的 meminfo 信息

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

2.查看步骤

这里我不断进入我的应用界面,发现 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>

3.查看具体源码

非静态内部类导致的内存泄露,比如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;            }        }    };

4.优化

@Override    protected void initValues() {        mHandler = new MyHandler(this);    }    private static class MyHandler extends Handler{
WeakReference
mActivity; 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; } } }

5.查看优化后结果

不断进入界面,查看 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

6.小结

这里进行省电模块的排查,尤其是对非静态内部类导致的内存泄露进行优化。

你可能感兴趣的文章
第六章 背包问题——01背包
查看>>
51nod 分类
查看>>
1136 . 欧拉函数
查看>>
面试题:强制类型转换
查看>>
Decorator模式
查看>>
Template模式
查看>>
Observer模式
查看>>
高性能服务器设计
查看>>
性能扩展问题要趁早
查看>>
MySQL-数据库、数据表结构操作(SQL)
查看>>
OpenLDAP for Windows 安装手册(2.4.26版)
查看>>
图文介绍openLDAP在windows上的安装配置
查看>>
Pentaho BI开源报表系统
查看>>
Pentaho 开发: 在eclipse中构建Pentaho BI Server工程
查看>>
JSP的内置对象及方法
查看>>
android中SharedPreferences的简单例子
查看>>
android中使用TextView来显示某个网址的内容,使用<ScrollView>来生成下拉列表框
查看>>
andorid里关于wifi的分析
查看>>
Spring MVC和Struts2的比较
查看>>
Hibernate和IBatis对比
查看>>