【问题标题】:Linux out of memory process killing my android appLinux内存不足进程杀死了我的Android应用程序
【发布时间】:2013-04-16 21:36:22
【问题描述】:

这发生在使用自定义构建的 Android 4.0.2 平台的嵌入式系统上。我看到我们的一个 android 活动应用程序增长到大约 400MB(调用“ps”时的 rss 大小)并被 Linux OOM 杀手杀死。 android 平台配置为最大堆大小设置为 62M。我不知道 Dalvik VM 如何让活动增长到 400MB。

当堆达到大约 60MB 时,应用程序不应该让 Java 出现内存不足异常吗? 我们在 logcat 日志或 anr 跟踪中看不到这些 Java 异常。

我们实现了一个示例活动,它按顺序分配字节数组并将每个字节设置为一个虚拟值。当活动分配大约 60MB 时,我们确实会看到内存不足异常。

android 中是否存在不计入堆预算的分配路径? 该活动呈现从网站下载的位图 png。

以下是我们平台上的“getprop”结果。

$ adb shell getprop | grep -i 堆

感谢任何指点。

谢谢

编辑: 笔记: 下面是ps输出。 Pss 和 Uss 大约是 316M 左右。

PID Vss Rss Pss Uss 命令行 logcat: hd[0]: pexecd(65): 982 351512K 351316K 326300K 316632K mytest.home^M logcat: hd[0]: pexecd(65): 660 679916K 61044K 57200K 56952K ./videngine^M RAM:总共 741764K,20320K 空闲,2148K 缓冲区,80104K 缓存,24964K shmem,10368K 平板

【问题讨论】:

    标签: android out-of-memory


    【解决方案1】:

    本机代码中的直接分配不计入 Java 堆总数。可能还有其他可能性(可能是从文件映射和填充的页面?)。

    如果您有自定义的 android 版本,您可以设置 OOM 杀手值来保留您自己的应用程序。

    【讨论】:

    • 这是一个普通的安卓应用,没有任何自定义的 JNI 内容。我希望 JVM 抛出 OOM 异常,而不是让进程增长到 400MB。
    • 它可能不是自定义的(实际上我曾想过——也许是错误的——它甚至不是你的应用程序),但它有什么作用?平台代码中有很多 JNI。
    • 此应用程序使用 android 网络浏览器控件加载网页。看起来 Webkit 引擎会根据正在下载的页面在 Android Java 堆之外的本机代码中进行大量分配。这就解释了为什么应用会增长到 300MB 以上。
    【解决方案2】:

    我看到我们的一个 android 活动应用程序增长到大约 400MB(调用“ps”时的 rss 大小)

    引用 Dianne Hackborn,关于 Android 上 ps 的输出:“Vss 和 Rss 列基本上是噪音(这些是进程的直接地址空间和 RAM 使用情况,如果你将 RAM 相加跨进程使用,你会得到一个大得离谱的数字)”

    我衷心鼓励您阅读her epic SO answer on measuring an app's memory footprint。值得注意的是,除了我上面引用的引用之外,Rss 在她的分析中没有任何作用。因此,我建议不要担心 Rss,而是关注其他指标。

    【讨论】:

    • 我去看看线程。感谢分享。这就是我在调用“ps”时看到的。 logcat: hd[0]: pexecd(65): 982 351512K 351316K 326300K 316632K mytest.home^M logcat: hd[0]: pexecd(65): 660 679916K 61044K 57200K 56952K ./native_engine^M ...
    【解决方案3】:

    您可以执行以下操作来了解您的应用正在使用什么内存。

    转到 DDMS,并通过单击如下所示的图标创建堆转储:

    接下来使用 androir-sdk/tools 文件夹中的 hprof-conv 工具将 android 格式的 HPROF 转换为常规 HPROF 格式。

    接下来,使用Eclipse Memory Analyser (MAT) 打开堆转储,并查看支配树,在那里您将看到您的应用程序强制 Dalvik 垃圾收集器 (GC) 保留的变量列表。右键单击它们并转到“Path the GC root”和“Exclude Weak References”,将显示使这些对象保持活动状态的引用。查看是否有任何过期的引用被保留为内存泄漏。

    您可以观看this video 了解更多在 Android 应用程序中查找内存泄漏的详细方法。

    【讨论】:

    • 感谢您提供信息和链接。我们将修复内存泄漏。困扰我的是为什么 Dalvik 运行时没有抛出任何 OutOfMemory 异常。
    • 并不是所有的东西都分配在 Dalvik Heap 上,各种各样的东西都会变大,它们可能会反映在应用程序内存中(例如设置下正在运行的应用程序选项卡),例如 JIT 或其他东西别的。我真的建议您观看 I/O 的视频,它详细解释了堆上发生了什么,以及如何抛出 outOfMem Exp。
    猜你喜欢
    • 2018-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    相关资源
    最近更新 更多