cot*_*aws 22 memory heap android
我看到堆大小会随着应用程序的需要自动增加,直到手机的最大堆大小为止.我还看到最大堆大小因设备而异.
所以我的第一个问题是,Android设备上的典型Max Heap大小是多少?我已经在一部手机上测试了内存分配,该手机能够使用超过40mb的堆,而另一部手机在20的mbs中发出OutOfMemory错误.常用设备中最低的是什么,普通设备上最高的是什么?有标准还是平均?
第二个问题,更重要的一个问题,是如何确保您能够使用每台设备可用的资源,但避免使用太多?我知道有一些方法,比如onLowMemory(),但这些方法似乎只适用于整个系统内存,而不仅仅是特定应用程序的堆.
有没有办法检测设备的最大堆大小,还检测可用堆内存何时达到应用程序的低点?
例如,如果设备仅允许最大堆24mb并且应用程序接近分配的限制,那么它可以检测并缩小.但是,如果设备可以舒适地处理更多,它将能够利用可用的东西.
谢谢
早期设备的每个应用上限为16MB.后来的设备增加到24MB.未来的设备可能会更多可用.
该值是物理存储器的所述装置和所述显示装置的性能(因为能够显示更多的颜色的更大的屏幕通常需要较大的位图)上可用的反射.
编辑:额外的沉思......
我不久前读过一篇文章,指出垃圾收集分配器本质上是对具有无限内存的机器进行建模.您可以根据需要进行分配,并且会处理细节.Android主要以这种方式工作; 你一直到你需要的东西硬引用,中/弱引用的东西,你可能没有,并丢弃到你再也不需要这些东西的引用.GC将其全部排序.
在您的特定情况下,你会使用软引用保持周围,你没有的东西需要有在内存中,但想保持如果有足够的空间.
这开始与位图分离,很大程度上是因为一些早期的设计决策导致了"外部分配"机制.此外,软参考机制需要一些调整 - 初始版本倾向于保留所有内容或丢弃所有内容.
在Dalvik堆正在积极发展(见例如在Android 2.3"姜饼",它引入了一个并发GC音符),所以希望这些问题将在以后的版本中得到解决.
编辑:更新...
"外部分配"机制在4.0(冰淇淋三明治)中消失了.Bitmaps的像素数据现在存储在Dalvik堆上,避免了早先的烦恼.
最近的设备(例如Nexus 4)将堆大小限制在96MB或更高.
应用程序的内存限制的一般意义可以从"内存类"获得ActivityManager.getMemoryClass().可以从java.lang.Runtime函数中获得更具体的值maxMemory().
以下是某些特定设备的"正常"(见下文)堆大小:
我说"正常",因为某些版本的Android(例如,CyanogenMod)将允许用户手动调整堆限制.结果可以大于或小于"正常"值.
有关其他信息,请参阅此答案,包括如何以编程方式查明堆大小实际是什么,以及如何区分绝对堆大小限制和理想情况下应该遵循的堆限制:
要检测当前堆利用率,可以尝试使用Runtime类的totalMemory()方法.但是,我已经阅读过报告,Android OS的不同版本/实现可能有不同的策略,关于是否根据堆的最大值计算本机内存(从中分配位图的后备内存).而且,从3.0版开始,本机内存直接从应用程序自己的堆中获取.
这种计算的不确定性使我认为在运行时监视应用程序的内存使用情况是错误的,不断将其与可用数量进行比较.此外,如果您正处于涉及计算的中间,并且发现您的内存不足,则取消该计算并不总是方便或合理,如果您这样做,可能会给您的用户带来糟糕的体验.
相反,您可以尝试在应用程序的功能行为上预先定义某些模式或约束,以确保它在任何当前设备的相关堆限制下(在应用程序初始化期间检测到).
例如,如果您的应用程序使用必须一次性加载到内存中的大量单词列表,那么您可以约束您的应用程序,以便对于较小的堆限制,只能加载较小的更常见单词列表,而对于较大的堆限制,可以加载包含更多单词的完整列表.
还有一些Java编程技术允许您根据需要声明某些内存可由垃圾回收器回收,即使它具有现有的"软"(而不是硬)引用.如果您有想要保留在内存中的数据,但是如果需要可以从非易失性存储中重新加载(即缓存),那么您可以考虑使用软引用让您的应用程序自动释放此类内存开始碰到堆的上限.有关Android中软引用的信息,请参阅此页面:
http://developer.android.com/reference/java/lang/ref/SoftReference.html