148

我有一个包含大量类的应用程序,还包括许多库,我正在设置android:largeHeap="true",因为我遇到了内存问题,附上了我的清单文件代码。

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="My Huge Application"
        android:largeHeap="true"
        android:logo="@drawable/logo"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme" >
</application>

我不得不问这是一个好习惯吗?请提出使用它的优点和缺点(优点和缺点)。

4

6 回答 6

137

在这里聚会太晚了,但无论如何我都会提供我的 0.02 美元。在这里使用谷歌的摘录来解释它
不是一个好主意, android:largeHeap="true"

但是,请求大堆的能力仅适用于一小部分可以证明需要消耗更多 RAM 的应用程序(例如大型照片编辑应用程序)。永远不要仅仅因为你的内存已经用完并且你需要一个快速修复就请求一个大堆——只有当你确切地知道所有内存被分配到哪里以及为什么必须保留它时才应该使用它。然而,即使您确信您的应用程序可以证明大堆是合理的,您也应该尽可能避免请求它。使用额外的内存将越来越多地损害整体用户体验,因为垃圾收集将花费更长的时间,并且在任务切换或执行其他常见操作时系统性能可能会变慢。

这是文档的完整链接 https://developer.android.com/training/articles/memory.html

更新

在与我一起工作后,out of memory errors我会说将其添加到清单中以避免 oom 问题并不是一种罪过,就像@Milad 在下面指出的那样,它不会影响应用程序的正常工作

更新 2

这里有一些应对技巧out of memory errors

1)使用android提供的这些回调onLowMemoryonTrimMemory(int) 并清除图像的缓存(如(毕加索,滑翔,壁画......)你可以在这里这里
阅读更多关于它们的信息 2)压缩你的文件(图像,pdf)
3)阅读如何在这里
更有效地处理位图 4) 在生产推送之前定期使用 lint 以确保代码简洁而不笨重

于 2015-06-19T05:01:26.337 回答
67

我认为这是一个非常有效的问题,让我补充一些关于使用此选项的优缺点的细节。

你得到什么 :

  • 显然,你会得到更大的堆,这意味着OutOfMemoryError.

你失去了什么:

  • 您可能会丢失一些帧,这可能会导致可见的卡顿。更大的堆使垃圾收集需要更长的时间。因为垃圾收集器基本上必须遍历您的整个活动对象集。通常,垃圾收集暂停时间约为 5ms,您可能认为几毫秒没什么大不了的。但每一毫秒都很重要。Android 设备必须每 16 毫秒更新一次屏幕,较长的 GC 时间可能会使您的帧处理时间超过 16 毫秒的障碍,这可能会导致明显的卡顿。

  • 切换应用程序也会变慢。Android 系统可能会从最近最少使用的进程开始杀死 LRU 缓存中的进程,但也会考虑哪些进程最占用内存。因此,如果您使用更大的堆,您的进程在后台运行时更有可能被杀死,这意味着当用户想要从其他应用程序切换到您的应用程序时可能需要更长的时间。当您的进程处于前台时,其他后台进程也更有可能被踢出,因为您的应用程序需要更大的内存。这意味着从您的应用切换到其他应用也需要更长的时间。

结论 :

尽量避免使用largeHeap选项。它可能会让您付出难以察觉的性能下降和糟糕的用户体验。

于 2016-05-16T08:44:33.347 回答
17

我有一个包含近 50 个课程的应用程序

我认为这不会造成太大问题。你得到 outOfMemory 错误的原因通常是在你的应用程序中加载了太多的图像或类似的东西。如果您不喜欢使用大堆,则必须找到一种优化内存使用的方法。

您还可以使用PicassoUILGlide等图像加载库。它们都具有在内存和/或磁盘上缓存图像的功能。

于 2014-12-10T09:46:55.337 回答
17

实际上android:largeHeap是增加分配给应用程序内存的工具。

没有明确定义需要使用此标志。如果您需要更多内存 - Android 为您提供了增加内存的工具。但是使用的必要性,你自己定义。

于 2014-12-10T09:08:26.490 回答
17

如果您必须使用(并保留)大量内存,那么是的,您可以并且应该使用android:largeHeap="true". 但是如果你确实使用它,你应该准备好让你的应用程序在其他应用程序处于前台时从内存中刷新。

“做好准备”是指您应该针对这种可能性进行设计,以便尽可能高效地编写您的方法onStop()和方法,同时确保以向用户呈现无缝外观的方式保存和恢复所有相关状态。onResume()

有与此参数相关的三种方法:maxMemory()getMemoryClass()getLargeMemoryClass()

对于大多数设备,默认情况下maxMemory()将表示一个相似getMemoryClass()的值,尽管后者以兆字节表示,而前者以字节表示。

当您使用该largeHeap参数时,maxMemory()将增加到特定于设备的更高级别,而getMemoryClass()将保持不变。

getMemoryClass()不会限制您的堆大小,但它会告诉您如果您希望您的应用程序在您运行的特定设备的限制内舒适兼容地运行,您应该使用的堆数量。

maxMemory()相比之下,确实会限制您的堆大小,因此您确实可以通过增加其值来访问额外的堆,并且largeHeap确实会增加该值。但是,增加的堆数量仍然是有限的,并且该限制将是特定于设备的,这意味着您的应用程序可用的堆数量会有所不同,具体取决于运行您的应用程序的设备的资源。因此,使用largeHeap并不是让您的应用程序放弃所有谨慎并在自助餐中找到自己的方式。

largeHeap您的应用程序可以通过调用方法使用参数来准确发现特定设备上可用的内存量getLargeMemoryClass()。返回的值以兆字节为单位。

这篇较早的文章包括对该largeHeap参数的讨论,以及一些示例,说明在几个特定的​​ Android 设备上使用和不使用它时可用的堆数量:

检测 Android 中的应用程序堆大小

我没有部署任何我自己的应用程序将此参数设置为 true。但是,我的一个应用程序中有一些内存密集型代码用于编译一组与优化相关的参数,这些参数仅在开发期间运行。我largeHeap只在开发过程中添加参数,以避免在运行此代码时出现内存不足错误。但是我在部署应用程序之前删除了参数(和代码)。

于 2018-09-15T07:59:05.317 回答
4

是否应使用大型 Dalvik 堆创建应用程序的进程。这适用于为应用程序创建的所有进程。它仅适用于加载到进程中的第一个应用程序;如果您使用共享用户 ID 来允许多个应用程序使用一个进程,则它们都必须一致地使用此选项,否则它们将产生不可预知的结果。

大多数应用程序不应该需要这个,而是应该专注于减少它们的整体内存使用以提高性能。启用此功能也不能保证可用内存的固定增加,因为某些设备受到其总可用内存的限制。

于 2014-12-10T09:04:12.293 回答