adb获取内存实时消耗_adb查看内存泄露 leak memory

本文介绍了如何使用adb工具进行内存实时消耗检查和内存泄露排查,包括通过`adb shell dumpsys activity`查看活动信息,利用`adb shell dumpsys meminfo`监控内存使用,以及分析内存泄露案例和解决方案。此外,还提到了使用Eclipse的DDMS内存分析工具进行更深入的内存泄漏检测。
摘要由CSDN通过智能技术生成

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.magellangps.SmartGPS

adb shell dumpsys meminfo com.charlie.demo0108

通过adb shell dumpsys meminfo 来查看内存使用状况

在没有打开应用的情况下,该命令返回的数据是这样的:

ad05dcc9d2e0

dumpsys未打开应用

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

ad05dcc9d2e0

image.png

内存泄露的一个例子

如下代码:

import java.util.ArrayList;

public class ManagerTest {

public static ManagerTest managerTest;

public static ManagerTest getInstance() {

if(managerTest==null) {

managerTest=new ManagerTest();

}

return managerTest;

}

ArrayList listeners=new ArrayList();

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

eclipse 内存分析工具

切换到DDMS页面,左上角如图,点击按钮,会提示保存,当前的内存信息到一个文件[没有插件是这样的]

你得从设备下边点击一下你要分析的app的包名,然后上边按钮才是可用状态

ad05dcc9d2e0

image.png

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

ad05dcc9d2e0

image.png

完事就会弹出一个下边的页面,选择histogram,顶部的菜单或者下边那个都行

然后你会看到几十条,最后一行会告诉你有比如4000条这里就显示了30条。所以过滤条件就很有必要了。

输入你怀疑内存泄露的类的名字,回车过滤,下图为过滤的结果

ad05dcc9d2e0

image.png

然后如下图,找到关联的

ad05dcc9d2e0

image.png

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

ad05dcc9d2e0

image.png

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

ad05dcc9d2e0

image.png

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

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

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

ad05dcc9d2e0

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的写法

最近看了个帖子,kotlin的写法

在一个activity里调用下边的方法,然后关闭页面,然后发现没有内存泄露一说

private fun testR(){

thread {

Thread.sleep(15000)

}

}

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

var aa=1

private fun testR(){

thread {

aa=2

Thread.sleep(15000)

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值