zoukankan      html  css  js  c++  java
  • 【原创】Android内存管理-OnTrimMemory

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

      @CallSuper
        public void onLowMemory() {
            Object[] callbacks = collectComponentCallbacks();
            if (callbacks != null) {
                for (int i=0; i<callbacks.length; i++) {
                    ((ComponentCallbacks)callbacks[i]).onLowMemory();
                }
            }
        }
    
        @CallSuper
        public void onTrimMemory(int level) {
            Object[] callbacks = collectComponentCallbacks();
            if (callbacks != null) {
                for (int i=0; i<callbacks.length; i++) {
                    Object c = callbacks[i];
                    if (c instanceof ComponentCallbacks2) {
                        ((ComponentCallbacks2)c).onTrimMemory(level);
                    }
                }
            }
        }
    

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

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

    先重点介绍一下onTrimMemory

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

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

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

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

    1. 回调时机

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

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

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

    2.level值的具体含义

     /**
         * Level for {@link #onTrimMemory(int)}: the process is nearing the end
         * of the background LRU list, and if more memory isn't found soon it will
         * be killed.
         */
        static final int TRIM_MEMORY_COMPLETE = 80;
        
        /**
         * Level for {@link #onTrimMemory(int)}: the process is around the middle
         * of the background LRU list; freeing memory can help the system keep
         * other processes running later in the list for better overall performance.
         */
        static final int TRIM_MEMORY_MODERATE = 60;
        
        /**
         * Level for {@link #onTrimMemory(int)}: the process has gone on to the
         * LRU list.  This is a good opportunity to clean up resources that can
         * efficiently and quickly be re-built if the user returns to the app.
         */
        static final int TRIM_MEMORY_BACKGROUND = 40;
        
        /**
         * Level for {@link #onTrimMemory(int)}: the process had been showing
         * a user interface, and is no longer doing so.  Large allocations with
         * the UI should be released at this point to allow memory to be better
         * managed.
         */
        static final int TRIM_MEMORY_UI_HIDDEN = 20;
    
        /**
         * Level for {@link #onTrimMemory(int)}: the process is not an expendable
         * background process, but the device is running extremely low on memory
         * and is about to not be able to keep any background processes running.
         * Your running process should free up as many non-critical resources as it
         * can to allow that memory to be used elsewhere.  The next thing that
         * will happen after this is {@link #onLowMemory()} called to report that
         * nothing at all can be kept in the background, a situation that can start
         * to notably impact the user.
         */
        static final int TRIM_MEMORY_RUNNING_CRITICAL = 15;
    
        /**
         * Level for {@link #onTrimMemory(int)}: the process is not an expendable
         * background process, but the device is running low on memory.
         * Your running process should free up unneeded resources to allow that
         * memory to be used elsewhere.
         */
        static final int TRIM_MEMORY_RUNNING_LOW = 10;
    
    
        /**
         * Level for {@link #onTrimMemory(int)}: the process is not an expendable
         * background process, but the device is running moderately low on memory.
         * Your running process may want to release some unneeded resources for
         * use elsewhere.
         */
        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.

  • 相关阅读:
    C/C++ 数据精确度的设置
    Java 接口回调
    ListView + ArrayAdapter + 接口回调
    C/C++内存详解
    第九届蓝桥杯明码
    2018蓝桥杯省赛(C/C++ C组)
    2015蓝桥杯五星填数(C++C组)
    java ee 面试时的机试题
    让div中的table居中
    javascript 调试技巧
  • 原文地址:https://www.cnblogs.com/weiwangnuanyang/p/5706981.html
Copyright © 2011-2022 走看看