如何增加android应用程序的堆大小?

Posted

技术标签:

【中文标题】如何增加android应用程序的堆大小?【英文标题】:How to increase heap size of an android application? 【发布时间】:2012-07-01 19:17:03 【问题描述】:

我正在编写一个使用多个 3D 模型的 android 应用程序。这种带有纹理的模型会占用大量内存。我发现制造商对应用程序可以使用的堆大小设置了限制。例如我的平板三星 Galaxy Tab 8.9 P7310 可以占用 64MB 内存。

有没有办法增加应用程序可以使用的内存大小?

【问题讨论】:

【参考方案1】:

您可以使用 android:largeHeap="true" 请求更大的堆大小,但这不适用于任何预 Honeycomb 设备。在 2.3 之前的设备上,您可以使用 VMRuntime 类,但这不适用于 Gingerbread 及更高版本。

获得尽可能大的限制的唯一方法是通过 NDK 执行内存密集型任务,因为 NDK 不像 SDK 那样施加内存限制。

或者,您可以仅加载当前视图中的模型部分,并根据需要加载其余部分,同时从内存中删除未使用的部分。但是,这可能是不可能的,具体取决于您的应用。

【讨论】:

这完全取决于你有什么代码。我不是 NDK 的专家,只知道基础知识。我建议您在 android-ndk Google 群组上提出这个问题以及对您的代码的描述,或者使用 android-ndk 标签在 SO 上发布一个新问题。 largeHeap=true FTW android api 的开发者真的很有趣,他们就像你想要更多的堆?好的,请求它,它只适用于那些需要它的人......同时每个开发人员都将它作为应用程序投入生产时添加的第一件事:) @cregox Unity 可以构建到 C++,如果我们选择构建类型是 Il2CPP in PlayerSettings link 所以我认为如果我们想做任何需要良好性能的繁重事情,那么我们可以通过 Unity 构建,导出到模块并将该模块导入 Android @dung 感谢更新!到现在为止,我得到了一个更好且完全摆脱了整个盒子“解决方案”(至少对我自己而言),但是如果我只告诉你 1 个词,你会认为这简直是疯狂的脱节题……相反,我会只是说我没有超过 5 年的编码,并且没有超过 1 年的计算机,如果我继续走这条路,我永远不会像今天这样快乐或有成就。干杯!【参考方案2】:

有没有办法增加应用程序可以使用的内存大小?

在 API 级别 11+ 上运行的应用程序可以在清单中的 <application> 元素上使用 android:largeHeap="true" 来请求比正常更大的堆大小,ActivityManager 上的 getLargeMemoryClass() 会告诉您该堆有多大是。然而:

    这仅适用于 API 级别 11+(即 Honeycomb 及更高版本)

    无法保证大堆有多大

    用户会感知到您的大堆请求,因为它会强制其他应用程序退出 RAM 终止其他应用程序的进程以释放系统 RAM 以供您的大堆使用

    由于#3,以及我预计android:largeHeap 将被滥用的事实,将来可能会放弃对此的支持,或者可能会在安装时警告用户(例如,您需要为其申请特殊许可)

    目前,此功能的文档很少

【讨论】:

@CommonsWare 如果没有 largeHeap 可用,如何删除以前加载的对象(如图像)? @MiguelRivera:对于图像,理想情况下你可以回收它们的内存(参见inBitmap 上的BitmapOptions)。除此之外,删除对它们的所有引用,最终它们将被垃圾回收。 你建议什么决定? @zest:我不知道你指的是什么,抱歉。 @Eftekhari:不是直接用于您的应用程序。拥有更多的东西可能会导致您花费更多的 CPU 时间来处理这些东西,但那里的细节将取决于您对内存所做的事情,并且与请求 android:largeHeap 没有直接关系。但是,请求大堆可能会通过强制其他应用程序进程提前终止而损害整体用户体验。【参考方案3】:

您不能动态增加堆大小。

您可以通过在清单中使用android:largeHeap="true" 来请求使用更多。

另外,您可以使用 native memory (NDK & JNI) ,因此您实际上绕过了堆大小限制。

这里有一些关于它的帖子:

How to cache bitmaps into native memory

JNI bitmap operations , for helping to avoid OOM when using large images

这是我为它制作的一个库:

https://github.com/AndroidDeveloperLB/AndroidJniBitmapOperations

【讨论】:

@ 每个应用程序在 java 级别的堆限制和本机不同吗?即 s5 设备上的示例 128mb Java 堆限制和本机可以占用另一个 128 mb? 每个应用程序的堆大小是恒定的(大小取决于硬件和 rom),并且应该对所有应用程序都相同。本机内存是设备中真正的内存,但它当然也受到限制,因为其中一些被操作系统使用。 我的意思是如果我的应用程序使用的是原生 .so+ java android Platform + java POJO 逻辑 + javascript。 android在每个级别都有不同的堆大小吗? ***.com/questions/47714637/… @NitZRobotKoder 否。堆大小适用于 Java/Kotlin 世界,如果使用过多,可能会出现 OOM 异常。剩下的就是原生内存。【参考方案4】:

使用第二个过程。在AndroidManifest 声明新的Service

android:process=":second"

第一个和第二个进程通过BroadcastReceiver交换

【讨论】:

【参考方案5】:

这可以根据您的 Android 操作系统通过两种方式完成。

    您可以在 Android 清单的应用程序标记中使用 android:largeHeap="true" 来请求更大的堆大小,但这不适用于任何预 Honeycomb 设备。 在 2.3 之前的设备上,您可以使用 VMRuntime 类,但这不适用于 Gingerbread 及更高版本,请参阅下文。
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

在设置 HeapSize 之前,请确保您已输入适当的大小,不会影响其他应用程序或操作系统的功能。在设置之前,只需检查您的应用需要多少大小,然后设置大小以完成您的工作。不要使用太多内存,否则可能会影响其他应用程序。

参考:http://dwij.co.in/increase-heap-size-of-android-application

【讨论】:

显然, 2.3 有办法,但 2.3 搞砸了!【参考方案6】:

据我所知,您可以在早期的 Android 版本中使用 VMRuntime 类,但现在您不能再使用了。

我不认为让开发人员在移动环境中选择堆大小可以被认为是安全的。我认为通过尝试从应用程序本身修改堆大小,您可以更容易地找到一种方法来修改特定设备(而不是编程端)中的堆大小。

【讨论】:

【参考方案7】:

增加 Java 堆不公平地消耗了移动资源的不足。有时只需等待垃圾收集器,然后在堆空间减少后恢复操作就足够了。然后使用这个static method。

【讨论】:

以上是关于如何增加android应用程序的堆大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何增加.NET 的堆大小? [复制]

如何检测 android 应用程序的堆大小使用情况

关于增加 JVM 的堆大小

由于堆大小增加,android中的内存不足错误

如何在 Java ME 中增加堆大小?

JVM 的堆大小不断增加(但 usedMemory() 不断减少)