将largeHeap设置为true有什么好处?


122

我有一个正在设置的课程,其中包含将近50个课程android:largeHeap="true",如下所示。这是一个好习惯吗?

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

请提出使用它的优点和缺点。

我遇到内存问题,这就是为什么我问这个问题。


如果您需要大容量的应用程序(例如游戏3dmodels等)
januprasad 2014年

47
50班不是很多。
克里斯·海斯


如果您正在使用某些服务或应用程序中消耗内存的任何其他应用程序,则您的应用程序会遇到内存问题,例如相机是使用该应用程序时开发人员最常遇到的问题,或者您有很多变量在消耗内存或静态变量变量也可能是其原因。
阿迪蒂

4
类的数量并不重要。位图通常会占用大量内存。请参阅“ 将按比例缩小的版本加载到内存中 ”。
ToolmakerSteve

Answers:


116

对于这里的聚会来说太晚了,但是我还是会提供我的0.02 $。
使用 android:largeHeap="true" Google的摘录对此进行解释不是一个好主意

但是,请求大堆的能力仅适用于少数可以证明需要消耗更多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)在进行生产前定期使用棉绒,以确保代码光滑而不笨重


1
为什么说“它不影响应用程序的正常工作”?这个答案讨论了一些后果。在其他地方,我发现在某些应用程序上使用largeHeap GC测量的时间甚至更糟。
ToolmakerSteve

59

我认为这是一个非常有效的问题,让我添加一些使用此选项的优缺点的详细信息。

你得到什么 :

  • 显然,您会获得更大的堆,这意味着降低的风险OutOfMemoryError

你输了什么:

  • 您可能会丢失一些帧,这可能会导致可见的挂钩。较大的堆会使垃圾回收花费更长的时间。因为垃圾收集器基本上必须遍历整个活动对象集。通常,垃圾回收的暂停时间约为5毫秒,您可能会认为几毫秒不是什么大问题。但是每毫秒都会计数。Android设备必须每16毫秒更新一次屏幕,更长的GC时间可能会使您的帧处理时间超过16毫秒,这可能会导致可见的跳动。

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

结论:

largeHeap尽可能避免使用option。这可能会导致您难以注意到的性能下降和糟糕的用户体验。


17

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

我认为这不会造成太大问题。出现OutOfMemory错误的原因通常是在您的应用中加载了太多图像或类似的图像。如果你不快乐使用一大堆,你必须找到一种方法,使用内存优化。

您还可以使用图像加载库,例如PicassoUILGlide。它们都具有在内存和/或磁盘中进行图像缓存的功能。


1
对于图像加载,我通常建议使用picaso或通用图像加载器
Mightian 2015年

5
相较于毕加索,滑翔效果更好,优化程度更高
Damien Praca

1
@DamienPraca我不这么认为,至少如果您在毕加索中正确使用了标签(setTag(),pauseTag(),resumeTag())。
Ruslan Berozov '19

15

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

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


4
是的,有一个明确的定义,请参考此链接developer.android.com/training/articles/memory.html
Mightian 2015年

2
@war_Hero-也许该文章已更改其内容?在其中没有提及largeHeap。
ToolmakerSteve

7

如果必须使用(并保留)大量内存,那么可以,并且可以使用android:largeHeap="true"。但是,如果您确实使用过它,则应该准备在其他应用程序出现在前台时从内存中清除您的应用程序。

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

有三种方法,涉及到这个参数:maxMemory()getMemoryClass(),和getLargeMemoryClass()

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

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

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

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

largeHeap通过调用该方法,您的应用程序可以通过使用参数确切地发现将在特定设备上提供多少内存getLargeMemoryClass()。返回的值以兆字节为单位。

这篇较早的文章讨论了该largeHeap参数,并提供了一些示例,说明了在几个特定的​​Android设备上使用和不使用它都可以使用多少堆:

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

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


1
“摒弃一切谨慎,直视自助餐”
约书亚·品特

4

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.