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

131

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

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

7个回答

213

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

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

或者,您可以仅加载当前可见部分的模型,并在需要时加载其余部分,同时从内存中删除未使用的部分。然而,这取决于您的应用是否可以这样做。


3
这完全取决于你拥有的代码。我不是NDK方面的专家,只知道一些基础知识。我建议你在android-ndk Google组中提出这个问题,并附上你的代码描述,或者在SO上发布一个带有android-ndk标签的新问题来进行特定的提问。 - Raghav Sood
4
largeHeap=true 赢了 - Luis Artola
2
Android API的开发人员真的很有趣,他们就像是在说:“你想要更多的堆内存?好的,请求吧,这只是为那些需要它的人准备的……与此同时,每个开发人员都会把它作为第一件事添加到应用程序上线的清单中 :)” - AndroidLover
1
@cregox 如果我们在PlayerSettings中选择构建类型为Il2CPP,Unity可以构建到C++ 链接,因此我认为如果我们想要做任何需要良好性能的重型任务,我们可以通过Unity构建它,将其导出到模块并将该模块导入到Android。 - DungPhan
1
@dung 谢谢你的更新!现在我有一个更好的、完全脱离这个“盒子”的“解决方案”(至少对我来说),但如果我只告诉你一个词,你会认为它是完全疯狂和不相关的。相反,我只想说,我已经超过5年没有编程了,也没有电脑超过1年,如果我继续走这条路,我永远不可能像今天这样快乐和成功。干杯! - cregox
显示剩余3条评论

111
有没有办法增加应用程序可以使用的内存大小?
运行在API 11+上的应用程序可以在清单文件中的元素上添加android:largeHeap =“true”来请求比正常堆大小更大的堆大小,getLargeMemoryClass()方法可以告译你这个堆有多大。然而:
1. 这仅适用于API级别11+(即Honeycomb及以上)。 2. 没有保证大堆大小会有多大。 3. 用户会察觉到您对大堆的请求,因为它将终止其他应用程序进程以释放系统RAM供您使用。 4. 基于问题#3以及我预计android:largeHeap将被滥用,支持此功能可能会在将来被放弃,或者用户可能在安装时收到警告(例如,您需要请求特殊权限才能使用)。 5. 目前,这个功能的文档非常简略。

@CommonsWare 如果没有可用的largeHeap,我该如何删除先前加载的对象(如图像)? - Jeongbebs
@MiguelRivera:对于图片,最好是回收它们的内存(请参见BitmapOptions中的inBitmap)。除此之外,删除所有对它们的引用,最终它们将被垃圾回收。 - CommonsWare
你有什么建议? - Henadzi Rabkin
@zest:抱歉,我不知道你在指什么。 - CommonsWare
2
@Eftekhari:对于您的应用程序来说,不是直接的。拥有更多的内容可能会导致您花费更多的CPU时间去处理这些内容,但具体情况取决于您如何使用内存,而不是直接与请求android:largeHeap相关。然而,请求大堆可能会损害用户的整体体验,因为它会迫使其他应用程序进程比本来需要的更早地终止。 - CommonsWare
显示剩余7条评论

23

每个应用程序在Java层面的堆限制和本地堆限制是不同的吗?例如,在S5设备上,128MB的Java堆限制和本地堆可以再占用128MB吗? - NitZRobotKoder
堆大小对于每个应用程序都是恒定的(大小取决于硬件和ROM),并且应该对所有应用程序相同。本机内存是设备的实际内存,但它当然也是有限的,因为其中一些被操作系统使用。 - android developer
我指的是如果我的应用程序使用本地的.so+ Java Android平台+ Java POJO逻辑+ JavaScript。在每个级别上,Android的堆大小是否不同? - NitZRobotKoder
https://stackoverflow.com/questions/47714637/android-profiler-vs-java-api-level-memory-calculation - NitZRobotKoder
@NitZRobotKoder 不是的。堆大小是针对Java/Kotlin世界的,如果使用过多可能会导致OOM异常。对于其他情况,它是本机内存。 - android developer

7

使用第二个进程。在 AndroidManifest 中声明一个新的 Service

android:process=":second"

使用BroadcastReceiver在第一和第二进程之间进行交互


5

根据您的Android操作系统,有两种方法可以实现。

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

在设置堆大小之前,请确保您输入的大小是适当的,不会影响其他应用程序或操作系统功能。在进行设置之前,仅检查您的应用程序占用了多少空间,然后设置大小以满足您的工作需求。不要使用过多的内存,否则可能会影响其他应用程序。

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


4
显然,小于2.3有一种方法,大于2.3有一种方法,但是2.3就很棘手! - Michael

4

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

我认为在移动环境中允许开发人员选择堆大小并不是很安全。我认为更容易找到一种方法来在特定设备上修改堆大小(而不是在编程方面尝试从应用程序本身进行修改)。


0

增加Java堆会不公平地消耗移动设备的资源。有时候只需要等待垃圾回收器,然后在堆空间减少后恢复操作即可。使用此静态方法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接