且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

检测 Android JNI 代码中的本机内存泄漏

更新时间:2023-08-19 18:41:34

2017 年更新: valgrind 可用于 Android .Android N,对于查找内存泄漏非常有用.您可能需要 _exit() 应用程序来触发转储.

2017 update: valgrind is available for Android. The built-in malloc debug feature was expanded significantly in Android N, and is quite useful for finding memory leaks. You may need to _exit() the app to trigger the dump.

下面描述的 DDMS 功能目前在 简要提及官方文档.

The DDMS feature described below currently gets a brief mention in the official docs.

有一个实验性的、不受支持的功能,您可以利用它.

There is an experimental, unsupported feature that you may be able to take advantage of.

在您的 DDMS 配置文件(例如 Linux 上的 ~/.android/ddms.cfg)中,添加native=true".这将启用 Native Heap 选项卡.

In your DDMS configuration file (e.g. ~/.android/ddms.cfg on Linux), add "native=true". This enables the Native Heap tab.

接下来,在设备上启用本机堆分配跟踪,并重启应用框架:

Next, enable native heap allocation tracking on the device, and restart the app framework:

% adb shell setprop libc.debug.malloc 1 
% adb shell stop 
% adb shell start 

(请注意,这需要 root.另请注意,这仅适用于最近的版本;在旧版本中,您还需要手动将 libc.so 替换为设备上/system/lib 中的 libc_debug.so.)

(Note this requires root. Note also that this only applies to recent releases; on older releases you also needed to manually replace libc.so with libc_debug.so in /system/lib on the device.)

您可以通过在发出简单命令(adb shell ls")时观察 logcat 输出来判断设备是否配置正确.如果你看到:

You can tell if you've got the device configured correctly by watching the logcat output while issuing a simple command ("adb shell ls"). If you see:

I/libc    ( 4847): ls using MALLOC_DEBUG = 1 (leak checker)

那么你知道你已经启用了它.

then you know you've enabled it.

现在您可以使用 Native Heap 选项卡功能来获取堆内存使用情况的快照.

Now you can use the Native Heap tab features to grab snapshots of heap memory usage.

DDMS 将自动从您的 Android 源代码树中的 .../symbols/system/lib 共享库中提取符号.当然,这要求您拥有完整的 Android 源代码树,并且您的设备正在运行由它构建的代码.否则,堆栈跟踪无法解码为符号名称,这会降低该功能的实用性.

DDMS will automatically extract symbols from the .../symbols/system/lib shared libraries in your Android source tree. Of course, this requires that you have a full Android source tree, and your device is running code built from it. If not, the stack traces can't be decoded to symbol names, which reduces the usefulness of the feature.