Heap Dumps 是诊断内存相关问题(如内存泄漏、垃圾收集问题和 java.lang.OutOfMemoryError )的重要工具。它们也是优化内存使用的重要工具。在本文中,我们提供了一些不同的方法来从 Android 应用程序捕获 Heap Dumps。一旦捕获了 Heap Dumps,就可以使用 HeapHero 和 Android Studio’s Heap Analyzer 等强大工具来分析 Heap Dumps。
Memory Profile
下面是在 Android Studio中从 Memory Profile (内存分析器)捕获 Heap Dumps 的步骤:
第一步:运行 app 并选择你要分析的设备。
第二步:在 Android Studio 中点击 View → Tool Windows → Android Profiler。
第三步:在 Android Profiler 中会有一个内存变化的时间轴,这个内存(MEMORY)时间轴位于处理器(CPU)时间轴之下,网络(NETWORK)时间轴之上。双击进入内存时间轴详情,然后就可以点击下载图标进行生成 Heap Dump, 如下图:
生成 Android 的 Heap Dump
第四步:要在系统中存储 Heap Dump,请单击下图中突出显示的图标。
保存 Android 的 Heap Dump 分析文件
第五步:选择一个本地存储文件夹,点击保存即可。
选择本地文件夹保存
ADB
Android Debug Bridge 是一个命令行工具,允许您与设备交互。ADB 提供各种设备操作,例如安装和调试应用程序。它还允许访问 Unix shell,以便在设备上运行各种命令。您可以使用此工具生成 Android Heap Dumps。启动 adb shell 并执行以下步骤:
第一步:识别你的 Android 应用程序的进程 ID.
第一步是确定您的 Android 应用的进程 ID。您可以通过以下命令来实现获取:
1
| adb shell ps | grep <APP-NAME>
|
这里需要注意的是如果不能执行,可以先执行 adb shell 切换到 root 用户:
adb shell 获取 Android 的进程 ID
上述命令将返回有关进程的详细信息。第二个数字是你的 app 的PID,
创建 Heap Dump
1
2
3
4
| adb shell am dumpheap <PID> <HEAP-DUMP-FILE-PATH>
PID: Your Android App Process Id
HEAP-DUMP-FILE-PATH: Location where heap dump file should be generated
|
例如:
1
| adb shell am dumpheap 27306 /data/local/tmp/android.hprof
|
把文件拉到你的 PC上
以上步骤将在设备中生成 Heap Dump 文件。为了进行分析,您需要将生成的文件拉到您的电脑上。您可以通过发出下面的命令来做到这一点:
1
2
3
| adb pull <HEAP-DUMP-FILE-PATH>
HEAP-DUMP-FILE-PATH: Location where heap dump file
|
例如:
1
| adb pull /data/local/tmp/android.hprof
|
在 OutOfMemoryError 异常上捕获 Heap Dumps
如果将以下代码放置在应用程序中,则当您的应用程序收到 OutOfMemoryError 时,它将捕获 Heap Dumps。
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
| public class CaptureHeapDumps extends Application {
private static final String FILE_NAME = "heap-dump.hprof";
@Override
public void onCreate() {
super.onCreate();
Thread.currentThread().setUncaughtExceptionHandler(OutOfMemoryException());
}
@NonNull
private Thread.UncaughtExceptionHandler OutOfMemoryException() {
return new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
String directory = getApplicationInfo().dataDir;
String absolutePath = new File(directory, FILE_NAME)
.getAbsolutePath();
try {
Debug.dumpHprofData(absolutePath);
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
}
|
这将在以下位置生成堆转储文件:/data/user/0/appname/heap-dump.hprof