大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢
转载请标明出处(http://blog.csdn.net/kifile),再次感谢
原文地址:http://developer.android.com/training/articles/memory.html
在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家
建议大家在看本文之前先去我的博客看看
[Android
性能优化系列]内存之基础篇--Android怎样管理内存
[Android
性能优化系列]内存之终极篇--减少你的内存消耗
以下是本次的正文:
################
应用应该怎样管理内存
在软件开发的各个阶段,你都应该时候注意你的RAM消耗(即便是在括软件的设计阶段)。这里有非常多种途径。通过使用它们能够帮助你设计和写出更有效率的代码。
你应该在设计和实现应用的时候採用下面的这些技术来让减少应用的内存消耗。
尽可能少的使用服务
假设你的应用须要使用服务来进行后台操作,那么尽可能让他在的确须要工作的时候才进行工作。
另外请确保当你的工作完毕之后结束掉你的服务。
当你开启一个服务的时候,系统会在服务执行的时候保留它的进程,这会让这个进行变得很庞大。由于服务所消耗的资源不能被其它应用使用或者回收。这就会导致保存在LRU缓存中的进程数量降低。使得切换应用的时候效率降低。当后台有足够多的服务正在执行的时候,他甚至可能导致整个系统由于内存紧张而崩溃掉。
管理你的服务最简单的方法是使用一个IntentService,他会在他处理完事件之后自行关闭掉服务。详情请參看使用前台服务。
当不须要的时候还让服务一直在后台执行是内存管理中最不应该犯的错之中的一个。因此不要贪心的让自己的服务一直在后台执行,这不仅会导致你应用的性能变低,用户也有可能发现应用的这样的行为而且卸载他。
当用户界面隐藏起来的时候,释放掉内存资源
当用户切换到其它应用,你的ui界面不可见的时候。你就应该释放掉那些被自己界面使用的资源。在这个时候释放掉ui资源可以显著提升系统存放缓存进程的数目,这可以极大的提升用户体验。
当你应用中的全部进程的界面对于用户而言都不可见的时候。会触发onTrimMemory()的回调接口。带着一个TRIM_MEMORY_UI_HIDDEN參数。
这个接口同OnStop()的回调接口的不同在于 OnStop()接口会在应用跳转的时候被调用,而onTrimMemory接口仅仅有在全部界面都不可见的情况下被调用。虽然你须要实现onStop()方法来释放掉Activity资源,比如网络訪问或者注销掉广播接收器,但这还不够。你不应该在onTrimMemory之前就释放掉你的ui资源。
这可以保证用户通过返回键返回到你的应用中,你的ui资源相同存在,并且可以高速的显示出来。
当内存不足时释放掉一些内存
在你的应用的生命周期中,onTrimMemory()接口相同会在当整个设备的内存变得非常低的时候被调用。
你应该依据从onTrimMemory()中传来的内存等级,选择性的释放掉你资源
TRIM_MEMORY_RUNNING_MODERATE
你的应用正在执行,不可被杀死,可是眼下设备剩余内存非常少,系统须要从LRU缓存中杀死掉一些进程
TRIM_MEMORY_RUNNING_LOW
你的应用正在执行,不可被杀死。可是眼下设备剩余内存不足临界值,因此你须要释放掉不是用的内存来提升系统执行效率
TRIM_MEMORY_RUNNING_CRITICAL
你的应用正在执行,可是系统已经准备杀死大多数LRU中的进程,因此你应该释放掉那些不是非常关键的资源。
假设系统不能通过回收得到足够的RAM,那么他会清空全部LRU缓存,而且開始杀死那些希望保留的进程,比如拥有一个正在执行后台服务的进程。
相同的。当你的应用正在处于缓存中的时候,你可能会受到下面几个onTrimMemory()等级
TRIM_MEMORY_BACKGROUND
系统正在执行在低内存状态。而你的进程处在LRU列表的開始部分。
因此虽然你的应用进程不太可能被杀死。可是系统已经转杯開始杀死LRU中的进程。你应该释放掉那些easy被还原的资源。来确保你仍然在列表中。而且在用户返回到应用的时候可以高速的进行切换
TRIM_MEMORY_MODERATE
系统正在执行在低内存阶段,你的进程处于LRU列表的中部。增加系统无法获得足够的内存资源,你的应用将会被杀死
TRIM_MEMORY_COMPLETE
系统正在执行在低内存阶段。你的进程将会是最開始被系统杀死的进程之中的一个,你应该释放掉全部与你的应用状态无关的资源。
尽管因为onTrimMemory()接口直到API14的时候才被增加。你还是能够使用onLowMemory接口来作为老版本号的回调,他能够同onTrimMemory()中TRIM_MEMORY_COMPLETE的等级一样。
注意:当系统開始杀死在LRU缓存中的进程时。虽然他是从下至上開始的。可是他也会考虑优先杀死那些内存消耗比較大的,以回收很多其它的系统资源。因此,假设你的应用的内存尽可能低。你就可能被始终保留在内存中,可以非常快切换回来
推断你应该拥有多少内存
正如之前所提到的。每个Android设备都会依据自身RAM大小的不同来向应用提供不同大小的堆限制。你能够通过getMemoryClass()来得到应用可能拥有的堆的大小。增加你的应用当内存不足的时候却分配很多其它的内存,那么就会造成OOM
在一种很特殊的情况加,你能够通过设置manifest文件里<application>标签里的largeHeap的属性为true。假设你这么做,那么你能够通过getLargeMemoryClass()来获取你个比較大的堆的评估值。
虽然如此。最好仅仅有那些真正须要很多其它内存空间的应用才请求一个更大的堆空间,比如一个大型的图像编辑应用。
记住不要由于你内存溢出就去申请一个大型堆。你须要知道仅仅有你明确你的内存被分配到哪儿了,为什么他一直被保留着。
当你确信你的应用须要一个大型堆的时候,你应该避免任意浪费他,使用额外的内存会极大的影响用户的体验,由于垃圾回收会消耗很多其它的事件,而且系统的效率会在应用切换或者其它的操作上变得更慢
此外,一个大型堆的大小在不同的设备上不一样。当执行在某些拥有限制内存的设备上时。大型堆的大小可能同普通堆得大小一模一样。因此即使你使用了大型堆,你也应该通过getMemoryClass()来检查真正的堆的尺寸,以确保只是超出限制。