首页
社区
课程
招聘
[原创]OOM检测工具,第一版
发表于: 2024-1-25 15:31 3844

[原创]OOM检测工具,第一版

2024-1-25 15:31
3844

近期突然发现很多人对OOM比较关心,这里赋上一个使用说明

精简后代码最下方下载

如果需要,将会出第二版,会去除大量非必要代码

源:https://github.com/KwaiAppTeam/KOOM
更多好资源https://bbs.kanxue.com/user-home-854079.htm
下方源码有二次精简,只保留关键代码,方便2次开发

使用说明
由原来apk,7M多 缩小为 不到 2M,内存滴滴如金,且行且珍惜
图片描述
如图功能分为3部分:
(com.kwai.koom.demo.MainActivity入口)

1:Java 泄漏测试

(com.kwai.koom.demo.javaleak.JavaLeakTestActivity)

2:Native 泄漏测试

(com.kwai.koom.demo.nativeleak.NativeLeakTestActivity)

3:线程泄露测试(com.kwai.koom.demo.threadleak.ThreadLeakTestActivity)

一,Java 泄漏测试(JavaLeakTestActivity)

关键代码如下

1
2
3
4
5
6
7
8
9
10
11
12
//循环读取泄漏信息(个人觉得源代码JAVA/KT写的太一般,虽然改了一点,但还有很大的精简余地)
OOMMonitor.INSTANCE.startLoop(true, false, 5_000L);
 
//添加泄漏
LeakMaker.makeLeak(this);//Context oom
 
//五种泄漏方式
leakMakerList.add(new ActivityLeakMaker());
leakMakerList.add(new BitmapLeakMaker());
leakMakerList.add(new ByteArrayLeakMaker());
leakMakerList.add(new FragmentLeakMaker());
leakMakerList.add(new StringLeakMaker());

关键代码:
path:hprof文件保存位置,hprof文件下面再说

1
2
ForkStripHeapDumper.getInstance().dump(path);
ForkJvmHeapDumper.getInstance().dump(path);

最终执行代码:

1
2
3
4
5
6
7
8
9
int pid = suspendAndFork();//将本APP整个内存Fork一份(避免dumpHprofData出现卡顿)
if (pid == 0) {
  Debug.dumpHprofData(path);//耗时操作,将hprof保存到path
  exitProcess();
  Log.e(TAG,"PID :  "+pid);
} else if (pid > 0) {
 dumpRes = resumeAndWait(pid);
 Log.i(TAG, "dump " + dumpRes + ", notify from pid " + pid);
}

二,Native 泄漏测试(NativeLeakTestActivity)

关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//利用Application 可以监听Activity创建和销毁的功能,来捕获对应的Acivity的泄漏
AllocationTagLifecycleCallbacks.INSTANCE.register(getApplication(),NativeLeakTestActivity.this);
 
//开始循环监听(无力吐槽,代码结构太差)
LeakMonitor.INSTANCE.start();
 
nativeInstallMonitor(arr, arr2, monitorConfig.enableLocalSymbolic)
nativeSetMonitorThreshold(monitorConfig.monitorThreshold);
 
循环回调函数,size>0说明有native 层有泄露,会打印泄露大小等信息
@Override
public Boolean call() throws Exception {
    Map<String, LeakRecord> map = new HashMap<String, LeakRecord>();
    nativeGetLeakAllocs(map);
    AllocationTagLifecycleCallbacks.INSTANCE.bindAllocationTag(map);
    int size = map.size();
    Log.e(TAG, "泄露个数:" + size);
    if (size > 0) {
        for (String key : map.keySet()) {
            Log.e(TAG, "key: " + key + "  value: " + map.get(key).toString());
        }
    }
    LeakMonitorConfig config = (LeakMonitorConfig) monitorConfig;
    LeakListener leakListener = config.getLeakListener();
 
    return mIsStart;//false:循环遍历,不再监听泄漏信息
}
 
//创建navite层泄漏
NativeLeakTest.triggerLeak(new Object());

三,线程泄露测试

关键代码如下:

1
ThreadMonitor.INSTANCE.startTrackAsync();

不足的是只在版本 大于25 和小于 30之间使用(Build.VERSION.SDK_INT)

以上关键代码明白后,再分析整个项目,会更加清晰,

hprof文件说明:

内存完整数据
可使用MemoryAnalyzer(MAT)进行查看,方便分析内存占用
图片描述
图片描述

方便复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kwai.koom.demo2"  >
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="22" android:maxSdkVersion="24"/>
    <application
        android:name="com.kwai.koom.demo.KOOMApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.Holo.Light"
         >
        <activity android:name="com.kwai.koom.demo.MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.kwai.koom.demo.javaleak.test.ActivityLeakMaker$LeakedActivity" />
        <activity android:name="com.kwai.koom.demo.nativeleak.NativeLeakTestActivity" />
        <activity android:name="com.kwai.koom.demo.threadleak.ThreadLeakTestActivity" />
        <activity android:name="com.kwai.koom.demo.javaleak.JavaLeakTestActivity"  />
    </application>
 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
 
</manifest>

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2024-1-25 16:12 被富到流油^-^编辑 ,原因:
上传的附件:
收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 38
活跃值: (1907)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发
2024-1-25 15:40
0
雪    币: 506
活跃值: (3313)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
快乐的小跳蛙 沙发
你真快,可以下载了
2024-1-25 15:55
0
雪    币: 2328
活跃值: (10364)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
大佬可以把整个项目打包嘛
2024-1-26 09:47
0
游客
登录 | 注册 方可回帖
返回
//