我正在编写一个 Android 应用程序,它使用了几个3D 模型。这种带有纹理的模型可能会占用大量内存。我发现制造商对应用程序可以使用的堆大小设置了限制。例如,我的平板 Samsung Galaxy Tab 8.9 p7310可以占用64MB 的内存。
有没有办法增加应用程序可以使用的内存大小?
据我所知,在早期的 Android 版本中你可以使用 VMRuntime类,但是现在你不能了。
VMRuntime
我不认为让开发人员在移动环境中选择堆大小是如此安全的。我认为,您可以找到一种方法来修改特定设备(不是在编程方面)中的堆大小,而不是试图从应用程序本身修改它。
在 API Level 11 + 上运行的应用程序可以在清单中的 <application>元素上使用 android:largeHeap="true"来请求大于正常的堆大小,而 ActivityManager上的 getLargeMemoryClass()将告诉您堆有多大。然而:
<application>
android:largeHeap="true"
ActivityManager
getLargeMemoryClass()
这只适用于 API 级别11 + (即蜂巢和更高级别)
不能保证这个大堆会有多大
用户会察觉到您的大堆请求,因为它将 迫使其他应用程序退出 RAM终止其他应用程序的进程,以释放系统 RAM 供您的大堆使用
由于 # 3,以及我预计 android:largeHeap将被滥用的事实,这种支持在将来可能会被放弃,或者用户在安装时可能会被警告(例如,你需要为它请求一个特殊的权限)
android:largeHeap
目前,我们对这个特性进行了简单的记录
您可以使用 大堆 = “ true”来请求更大的堆大小,但是这不适用于任何之前的蜂窝设备。在 pre 2.3设备上,您可以使用 VMRuntime 类,但是在 Gingerbread 及以上版本上不能使用。
获得尽可能大的限制的唯一方法是通过 NDK 执行内存密集型任务,因为 NDK 不像 SDK 那样强加内存限制。
或者,您只能加载当前视图中的模型部分,并根据需要加载其余部分,同时从内存中删除未使用的部分。然而,这可能是不可能的,这取决于你的应用程序。
不能动态增加堆大小。
您可以通过在清单中使用 android:largeHeap="true"请求使用更多。
而且,可以使用 native memory (NDK & JNI),因此实际上可以绕过堆大小限制。
native memory (NDK & JNI)
以下是我为此发的一些帖子:
如何将位图缓存到本机内存中
JNI 位图操作,用于在使用大图像时帮助避免 OOM
这是我为它设计的图书馆:
根据您的 Android 操作系统,这可以通过两种方式来实现。
VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);
在设置 HeapSize 之前,请确保已经输入了不会影响其他应用程序或操作系统功能的适当大小。在设置之前,只要检查你的应用程序需要多少大小,然后设置大小,只是为了完成你的工作。不要使用这么多的内存,否则其他应用程序可能会影响。
参考资料: http://dwij.co.in/increase-heap-size-of-android-application
使用第二个进程。在 AndroidManifest声明新的 Service
AndroidManifest
Service
android:process=":second"
通过 BroadcastReceiver实现第一和第二进程之间的交换
BroadcastReceiver
增加 Java 堆不公平地吞噬了赤字移动资源。有时只需要 等待垃圾收集器,然后在减少堆空间后恢复操作就足够了。那就用这个 静态法。