安卓内存分配

Posted

技术标签:

【中文标题】安卓内存分配【英文标题】:Android memory allocation 【发布时间】:2011-01-09 01:42:18 【问题描述】:

我收到“位图大小超出 VM 预算”错误。我读过有一个 16MB 的内存限制。 In this thread Romain Guy 说“你只能分配 16 MB 整个应用程序的内存”。

但是,我的应用程序必须在达到该限制之前很久就耗尽内存。所以我的问题是:我如何为我的应用程序分配内存......我怎样才能增加对我的应用程序的分配(在最大 16MB 内)?

【问题讨论】:

好吧 640KB 足以满足任何谷歌慷慨... 【参考方案1】:

与任何 Java VM 一样,堆内存将自动增长到最大大小。但是,位图是在 VM 外部分配的,因此您不会在统计信息中轻松“看到”它们。您能做的最好的事情是确保您不使用大位图,或使用http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html

缩小它们

当您使用 Android 1.6 或更高版本时,您可以从 Eclipse 生成堆转储,并且可以使用 Eclipse MAT 分析转储。

通常您无法控制真实设备上的最大堆大小,除非您使用的是自定义硬件或固件。

developer.android.com 上应该有一篇关于在 1.6 上转储堆的文章,但我找不到。 :(

编辑 另外,我不得不提一下,您可以使用

为应用程序请求更多内存

android:largeHeap="true"

在清单中。但这是非常不明智的,因为大多数应用程序不需要它。

【讨论】:

谢谢。有时间我会看看堆转储和 MAT。 我刚刚注意到您说我可以获得堆转储并在 Android 1.6 上使用 Eclipse MAT。不幸的是,我的设备是 1.5,所以这就是我正在编程的目的。有没有简单的方法来获得 1.5 的内存分析? DDMS 中 SysInfo 中的内存使用图表包括显示每次屏幕旋转的使用量略有增加;它是否包括位图使用的非堆内存? DDMS 分配跟踪器没有显示任何显着的内存使用情况(假设它的单位是字节);除了位图之外,是否还有其他对象不会显示在 DDMS 分配跟踪器中? 您可以在 1.6 模拟器中运行您的代码进行调试,或者您可以尝试biowallet.blogspot.com/2009/04/… 此处描述的过程,或者您可以使用developer.android.com/reference/android/os/… 的 api 将堆从您的应用程序转储到您喜欢的位置。 android 1.5 也可以,检查kohlerm.blogspot.com/2010/02/… android:largeHeap="true" 不适用于 Application 标签。它在GB中被删除了吗?你知道有什么替代方法吗?【参考方案2】:

请注意,堆限制取决于设备。在 Droid 或 Nexus One 上,该限制为 24 MB(以容纳更大的图形资源。)

【讨论】:

Nexus S 也有 24MB,似乎大多数高端设备都会超过 16MB,但如果你想在任何设备上运行,你应该保持在 16MB 以下。 不,Nexus S 在 2.3 上有 32 MB。 我如何知道我的设备的堆限制? Runtime.getRuntime().maxMemory(); 我的 Nexus S 在 ICS 下有 48 MB。【参考方案3】:

如果您使用线程,则调试器可能是问题的根源。如果您在调试器下运行应用程序,则创建的任何线程仍将由调试器保留,即使它们已完成运行。这会导致应用在没有调试器的情况下运行时不会发生的内存错误。

http://code.google.com/p/android/issues/detail?id=7979

https://android.googlesource.com/platform/dalvik/+/master/docs/debugger.html

【讨论】:

谢谢。我想知道使用调试器是否会导致可能不会发生的内存问题。得到确认是件好事。【参考方案4】:

我最近找到了您问题的答案。

转到 Android SDK 目录并 运行sdk manager(Tools->android运行这个文件)

在 SDK 管理器中转到工具-->管理 AVD

现在 Android 虚拟设备管理器对话框已打开..

在该窗口中选择您的 AVD 并点击编辑

现在在 SD 卡部分选择 SIZE 并设置 1024 MiB 在硬件部分单击新建并选择属性“最大 VM 应用程序堆大小” 现在设置 100(根据您的应用要求) 最后点击“编辑AVD”

编辑后点击 sdk Manager 上的刷新按钮

现在在 AVD 中运行您的应用,您的问题就解决了。

【讨论】:

..与您的应用程序可用的内存和减少位图正在使用的内存几乎没有关系(几乎没有)。

以上是关于安卓内存分配的主要内容,如果未能解决你的问题,请参考以下文章

Android中的内存管理

Android中的内存管理

RK3399平台开发系列讲解(内存篇)18.12slub分配器的理念

安卓内存泄漏8种可能

RK3399平台开发系列讲解(内存篇)18.5为什么需要Slab

c语言分配内存方式都有哪些