adb查看内存泄露 leak memory

如何查看内存泄露https://blog.csdn.net/xyq046463/article/details/51769728
https://www.jianshu.com/p/48475df838d9
https://www.jianshu.com/p/cbe2ee08ca02

adb shell dumpsys activity | grep mFocusedActivity
可以查看当前正在展示的activity的信息,后边那个grep好像是linux的,我就用了前半部分,展示了好多信息,不过稍微往上滑一点就能看到

ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)
Display #0 (activities from top to bottom):
  Stack #1:
    Task id #1504
      TaskRecord{58cb3ac #1504 A=com.magellangps.SmartGPS U=0 sz=2}
      Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.xxx.SmartGPS/.StartupActivity }
        Hist #1: ActivityRecord{b5bc1bd u0 com.xxx.SmartGPS/.NavigationActivity t1504}
          Intent { flg=0x14000000 cmp=com.xxx.SmartGPS/.NavigationActivity }
          ProcessRecord{b8d5b25 18169:com.xxx.SmartGPS/u0a346}
        Hist #0: ActivityRecord{1039b10 u0 com.xxx.SmartGPS/.MainActivity t1504}
          Intent { flg=0x10000000 cmp=com.xxx.SmartGPS/.MainActivity (has extras) }
          ProcessRecord{b8d5b25 18169:com.xxx.SmartGPS/u0a346}

    Running activities (most recent first):
      TaskRecord{58cb3ac #1504 A=com.xxx.SmartGPS U=0 sz=2}
        Run #1: ActivityRecord{b5bc1bd u0 com.xxx.SmartGPS/.NavigationActivity t1504}
        Run #0: ActivityRecord{1039b10 u0 com.xxx.SmartGPS/.MainActivity t1504}

    mResumedActivity: ActivityRecord{b5bc1bd u0 com.xxx.SmartGPS/.NavigationActivity t1504}

adb在sdk的platform-tools目录下
adb如果没有配置环境变量的话,自己切换cmd下的目录到对应的目录即可

adb shell dumpsys meminfo com.xx.xxx
adb shell dumpsys meminfo com.xxx.demo0108
通过adb shell dumpsys meminfo <packageName>来查看内存使用状况
在没有打开应用的情况下,该命令返回的数据是这样的:

dumpsys未打开应用

打开这个应用的MainActivity,再通过命令查看:

image.png

Android adb命令打印activity堆栈

adb shell dumpsys activity | findstr Run

内存泄露的一个例子
如下代码:

import java.util.ArrayList;

public class ManagerTest {

    public static ManagerTest managerTest;
    
    public static ManagerTest getInstance() {
        if(managerTest==null) {
            managerTest=new ManagerTest();
        }
        return managerTest;
    }
    
    ArrayList<TestListener> listeners=new ArrayList<ManagerTest.TestListener>();
    
    public void registerListener(TestListener listener) {
        listeners.add(listener);
    }
    public interface TestListener{
        
        abstract void nothing();
    }
}

然后在activity使用了如下的代码,就内存泄露了,这个activity就一直存在了。

//内存泄露测试
                ManagerTest.getInstance().registerListener(new TestListener() {
                    
                    @Override
                    public void nothing() {
                        
                        
                    }
                });

解决办法就是在页面销毁的时候取消注册这个listener。所以这个listener得写到外边弄个变量保存。
另外一种如果不好取消注册的,可以如下图,把这个注册的listener置为空也可以好像不行

    TestListener listener=new TestListener() {
        @Override
        public void nothing() {
            
        }
    };
    @Override
    protected void onDestroy() {
        listener=null;
        super.onDestroy();
    }

总结一下,上边的也就是匿名内部类了吧,那个TestListener()接口,这玩意基本都会引起内存泄露的

获取连接到的设备信息

adb devices

C:\Users\xxx>adb shell "pm list packages" find samsung
package:com.samsung.android.app.galaxyfinder

打印设备/模拟器上的所有软件包

adb shell "pm list packages"
过滤名字

C:\Users\charlie.song>adb shell "pm list packages" -e  samsung
package:com.sec.android.widgetapp.samsungapps
package:com.samsung.android.app.galaxyfinder
package:com.samsung.clipboardsaveservice
package:com.samsung.android.provider.shootingmodeprovider

其他的一些option看这里
https://blog.csdn.net/henni_719/article/details/62222439

eclipse 内存分析工具

http://www.eclipse.org/mat/ 下边有下载地址
或 在 eclipse ->install new software -> http://download.eclipse.org/mat/1.6/update-site/ 进行安装
然后找篇介绍咋用 的
https://www.cnblogs.com/yxysuanfa/p/6811140.html

切换到DDMS页面,左上角如图,点击按钮,会提示保存,当前的内存信息到一个文件[没有插件是这样的]
你得从设备下边点击一下你要分析的app的包名,然后上边按钮才是可用状态


image.png

我是弄的插件,点击完按钮会直接弹出下边的框框,finish即可


image.png

完事就会弹出一个下边的页面,选择histogram,顶部的菜单或者下边那个都行
然后你会看到几十条,最后一行会告诉你有比如4000条这里就显示了30条。所以过滤条件就很有必要了。
输入你怀疑内存泄露的类的名字,回车过滤,下图为过滤的结果


image.png

然后如下图,找到关联的
image.png

然后发现太多了,继续过滤掉,选最后一个,


image.png

然后就会少很多,我这里过滤完就剩下一个context被引用了,会提示你哪个类的


image.png

然后找到这个类里的context,看是哪里传进来的,自然就知道是哪里的问题,然后就想办法是放掉。

context被一个静态变量给持有了

有个wifi的页面,最后查出来是这样的,刚开始完全不知道哪里有问题


image.png

搜了下wifimanager的类

private static AsyncChannel sAsyncChannel;

//init方法里初始化的,可以看到
                sAsyncChannel = new AsyncChannel();
                sConnected = new CountDownLatch(1);

                sHandlerThread.start();
                Handler handler = new ServiceHandler(sHandlerThread.getLooper());
                sAsyncChannel.connect(mContext, handler, messenger);
//进入到connect方法,其实可以猜到context被保存在了AsyncChannel类里了
 /** Context for source */
    private Context mSrcContext;
//一个静态变量持有了这个context,所以这个context的页面也就内存泄露了

所以最后修改的地方就是获取wifimanager的时候,用application的上下文

  protected WifiManager getWifiManager()
  {
    return (WifiManager) MainApplication.getAppContext().getSystemService(Context.WIFI_SERVICE);
  }

kotlin的写法

https://proandroiddev.com/how-kotlin-helps-you-avoid-memory-leaks-e2680cf6e71e

最近看了个帖子,kotlin的写法
在一个activity里调用下边的方法,然后关闭页面,然后发现没有内存泄露一说

    private fun testR(){
        thread {
            Thread.sleep(15000)
        }
    }

另一种,引用了activity里的一个变量,结果就不一样,会内存泄露的。

var aa=1
    private fun testR(){
        thread {
            aa=2
            Thread.sleep(15000)
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,100评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,308评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,718评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,275评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,376评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,454评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,464评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,248评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,686评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,974评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,150评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,817评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,484评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,140评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,374评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,012评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,041评论 2 351

推荐阅读更多精彩内容