Application中有两个与内存管理相关的方法:onLowMemory()和 onTrimMemory(int level),源码如下

  1. @CallSuper
  2. public void onLowMemory() {
  3. Object[] callbacks = collectComponentCallbacks();
  4. if (callbacks != null) {
  5. for (int i=0; i<callbacks.length; i++) {
  6. ((ComponentCallbacks)callbacks[i]).onLowMemory();
  7. }
  8. }
  9. }
  10.  
  11. @CallSuper
  12. public void onTrimMemory(int level) {
  13. Object[] callbacks = collectComponentCallbacks();
  14. if (callbacks != null) {
  15. for (int i=0; i<callbacks.length; i++) {
  16. Object c = callbacks[i];
  17. if (c instanceof ComponentCallbacks2) {
  18. ((ComponentCallbacks2)c).onTrimMemory(level);
  19. }
  20. }
  21. }
  22. }

从源码我们可以看到Application收到这两个回调时会通知它的监听者,而Activity和Service都注册了监听,

因此我们可以Application中重写这两个方法,也可以在组件中重写这两个方法。

先重点介绍一下onTrimMemory

为了更好的管理内存,OnTrimMemory 方法在 API-14 被引入。这个回调可以在所有组件中获取到(ActivityServiceContentProvider, and Application)。

你应该根据当前设备的限制复写 onTrimMemory(int) 来逐步的释放内存。通过复写这个方法释放资源可以帮助你的app更好的响应系统整体,同时通过让你的app

在系统中存活更久来提高用户体验。如果在系统内存很低时,你仍旧不释放内存,系统将会优先杀死你在的进程。这样当用户返回app时需要重启影响用户体验

onTrimMemory(int)的level值并不成线性关系,它只是提供了内存不同状态的线索。

1. 回调时机

  1. /**
  2. * Called when the operating system has determined that it is a good
  3. * time for a process to trim unneeded memory from its process. This will
  4. * happen for example when it goes in the background and there is not enough
  5. * memory to keep as many background processes running as desired. You
  6. * should never compare to exact values of the level, since new intermediate
  7. * values may be added -- you will typically want to compare if the value
  8. * is greater or equal to a level you are interested in.
  9. *
  10. * <p>To retrieve the processes current trim level at any point, you can
  11. * use {@link android.app.ActivityManager#getMyMemoryState
  12. * ActivityManager.getMyMemoryState(RunningAppProcessInfo)}.
  13. *
  14. * @param level The context of the trim, giving a hint of the amount of
  15. * trimming the application may like to perform. May be
  16. * {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE},
  17. * {@link #TRIM_MEMORY_BACKGROUND}, {@link #TRIM_MEMORY_UI_HIDDEN},
  18. * {@link #TRIM_MEMORY_RUNNING_CRITICAL}, {@link #TRIM_MEMORY_RUNNING_LOW},
  19. * or {@link #TRIM_MEMORY_RUNNING_MODERATE}.
  20. */
  21. void onTrimMemory(int level);

当操作系统认为这是一个进程释放无用内存的好时机时,会调用此方法。比如说当已经没有足够的内存来维持目前所有的后台进程,而此进程正好处于后台。
非常不推荐用一个精确的值来与level作比较,因为可能会增加新的差值,推荐的做法是判断一个值是否大于或者等于你感兴趣的level.

为了获取所有进程目前的level,你可以调用{@link android.app.ActivityManager#getMyMemoryState* ActivityManager.getMyMemoryState(RunningAppProcessInfo)}

2.level值的具体含义

  1. /**
  2. * Level for {@link #onTrimMemory(int)}: the process is nearing the end
  3. * of the background LRU list, and if more memory isn't found soon it will
  4. * be killed.
  5. */
  6. static final int TRIM_MEMORY_COMPLETE = 80;
  7.  
  8. /**
  9. * Level for {@link #onTrimMemory(int)}: the process is around the middle
  10. * of the background LRU list; freeing memory can help the system keep
  11. * other processes running later in the list for better overall performance.
  12. */
  13. static final int TRIM_MEMORY_MODERATE = 60;
  14.  
  15. /**
  16. * Level for {@link #onTrimMemory(int)}: the process has gone on to the
  17. * LRU list. This is a good opportunity to clean up resources that can
  18. * efficiently and quickly be re-built if the user returns to the app.
  19. */
  20. static final int TRIM_MEMORY_BACKGROUND = 40;
  21.  
  22. /**
  23. * Level for {@link #onTrimMemory(int)}: the process had been showing
  24. * a user interface, and is no longer doing so. Large allocations with
  25. * the UI should be released at this point to allow memory to be better
  26. * managed.
  27. */
  28. static final int TRIM_MEMORY_UI_HIDDEN = 20;
  29.  
  30. /**
  31. * Level for {@link #onTrimMemory(int)}: the process is not an expendable
  32. * background process, but the device is running extremely low on memory
  33. * and is about to not be able to keep any background processes running.
  34. * Your running process should free up as many non-critical resources as it
  35. * can to allow that memory to be used elsewhere. The next thing that
  36. * will happen after this is {@link #onLowMemory()} called to report that
  37. * nothing at all can be kept in the background, a situation that can start
  38. * to notably impact the user.
  39. */
  40. static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;
  41.  
  42. /**
  43. * Level for {@link #onTrimMemory(int)}: the process is not an expendable
  44. * background process, but the device is running low on memory.
  45. * Your running process should free up unneeded resources to allow that
  46. * memory to be used elsewhere.
  47. */
  48. static final int TRIM_MEMORY_RUNNING_LOW = 10;
  49.  
  50. /**
  51. * Level for {@link #onTrimMemory(int)}: the process is not an expendable
  52. * background process, but the device is running moderately low on memory.
  53. * Your running process may want to release some unneeded resources for
  54. * use elsewhere.
  55. */
  56. static final int TRIM_MEMORY_RUNNING_MODERATE = 5;

当你的app在后台时:

TRIM_MEMORY_COMPLETE :当前进程在LRU列表的尾部,如果没有足够的内存,它将很快被杀死。这时候你应该释放任何不影响app运行的资源。

TRIM_MEMORY_MODERATE :当前进程在LRU列表的中部,如果系统进一步需要内存,你的进程可能会被杀死。

TRIM_MEMORY_BACKGROUND:当前进程在LRU列表的头部,虽然你的进程不会被高优杀死,但是系统已经开始准备杀死LRU列表中的其他进程了,

因此你应该尽量的释放能够快速回复的资源,以保证当用户返回你的app时可以快速恢复。                   。

当你的app的可见性改变时:

TRIM_MEMORY_UI_HIDDEN:当前进程的界面已经不可见,这时是释放UI相关的资源的好时机。

当你的app正在运行时:

TRIM_MEMORY_RUNNING_CRITICAL:虽然你的进程不会被杀死,但是系统已经开始准备杀死其他的后台进程了,这时候你应该释放无用资源以防止性能下降。

下一个阶段就是调用"onLowMemory()"来报告开始杀死后台进程了,特别是状况已经开始影响到用户。

TRIM_MEMORY_RUNNING_LOW:虽然你的进程不会被杀死,但是系统已经开始准备杀死其他的后台进程了,你应该释放不必要的资源来提供系统性能,否则会

影响用户体验。

TRIM_MEMORY_RUNNING_MODERATE:系统已经进入了低内存的状态,你的进程正在运行但是不会被杀死。

再来说一下onLowMemory

在引入OnTrimMemory之前都是使用OnLowMemory方法。如果你的app运行在API-14+的机器上,应该使用 OnTrimMemory(int),OnLowMemory的调用时机大概等同于TRIM_MEMORY_COMPLETE.

【原创】Android内存管理-OnTrimMemory的更多相关文章

  1. Android内存管理-OnTrimMemory

    Application中有两个与内存管理相关的方法:onLowMemory()和 onTrimMemory(int level),源码如下 @CallSuper public void onLowMe ...

  2. Android 内存管理分析(四)

    尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...

  3. Android内存管理机制之一:low memory killer

    转载自http://www.miui.com/thread-29268-1-1.html 准备写这个专题之前,心里是有点忐忑的.首先Android内存管理机制相当复杂,想要讲清楚比较困难:其次对于绝大 ...

  4. 移动端测试===Android内存管理: 理解App的PSS

    Android内存管理: 理解App的PSS 原文链接:http://www.littleeye.co/blog/2013/06/11/android-memory-management-unders ...

  5. 浅谈Android内存管理

    最近在网上看了不少Android内存管理方面的博文,但是文章大多都是就单个方面去介绍内存管理,没有能全局把握,缺乏系统性阐述,而且有些观点有误,仅仅知道这些,还是无法从整体上理解内存管理,对培养系统优 ...

  6. [Android Memory] Android内存管理、监测剖析

    转载自:http://blog.csdn.net/anlegor/article/details/23398785 Android内存管理机制: Android内存管理主要有:LowMemory Ki ...

  7. Android——内存管理基础

    内存收集概念 内存垃圾收集器(garbage collector) 概念:自定内存管理. 功能:分配内存.保证所有被引用的对象还在内存中.可以释放在运行的代码中不再引用的对象的内存. 垃圾收集器避免了 ...

  8. 【原创】android内存管理-内存泄漏原因

    转载请注明出处 http://www.cnblogs.com/weiwangnuanyang/p/5704596.html 先讲一下内存泄漏的概念:内存泄露是指无用对象持续占有内存,或者内存得不到及时 ...

  9. Android内存管理(6)onTrimMemory,onLowMemory,MemoryInfo()

    转自: http://www.cnblogs.com/sudawei/p/3527145.html 参考: Android Application生命周期学习 Android中如何查看内存(上) An ...

随机推荐

  1. EF6 连接Oracle 迁移数据错误解决方法

    环境:vs2015 + EF6 +ODP 数据库Oracle 11G add-migratioin 正常,但在update-database 时报如下错误: System.Runtime.Serial ...

  2. 【转载】.NET模拟POST登录并保持登录状态

    好了,还是由于工作需要 要登录一个网站并且模拟点击下载某些东西 原理就是先对一个地址(地址是用户名和密码输入框所在的form的action对应的页面)进行POST提交用户名和密码(不考虑验证码,当然验 ...

  3. SQLSERVER不带JOIN的语句与带JOIN语句的区别

    //1.连接两个表查询 SELECT * FROM table1 t1,table2 t2 //2.连接两个表查询 SELECT * FROM table1 join table2 on table1 ...

  4. 终极解决maya渲染层丢材质,变线框等问题

    终极解决maya渲染层丢材质,变线框等问题 相信有很多同志在使用maya做灯光渲染的时候,经常能遇到渲染层的模型丢材质.变线框等问题,特别恶心.我也经常遇到,所以和大家分享一下我的解决或尽量避免的方法 ...

  5. 自定义windows新建菜单

    注册表下找到hkey_classes_root 找到想要新建的文件扩展名(.txt,.php,.html,.xml etc.) 创建名为ShellNew的键,再在其下添加NullType的项

  6. Qt 多线程和网络编程学习

    一,Qt多线程类学习 QThread类,开始一个新的线程就是开始执行重新实现QThread::run(),run()是默认现实调用exec(),QThread::start()开始线程的执行,run( ...

  7. Java ResourceBundle类的使用

    1.使用ResourceBundle读取配置文件 #数据库配置信息: DRIVER=com.mysql.jdbc.Driver URL=jdbc:mysql://localhost:3306/dmo ...

  8. 触发器事件trigger

    修改mysql结束符   delimiter name 触发器语法:     create trigger 触发器名称       after/before  触发时间     //错误  ERROR ...

  9. zend studio导入svn项目后不能代码提示的解决

    把项目下.project的文件内容改成如下: <?xml version="1.0" encoding="UTF-8"?><projectDe ...

  10. Hibernate5.2关联关系之单向多对一(二)

    Hibernate5.2之单向一对多(二) 一. 简介 在本篇博文中笔者会在上一篇博客的代码基础上进行修改,本篇文章将介绍单向的一对多. 二. hbm文件的方式 Customer.hbm.xml &l ...