【原創】Android內存管理-OnTrimMemory

Application中有兩個與內存管理相關的方法:onLowMemory()和 onTrimMemory(int level),源碼以下html

  @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都註冊了監聽,java

所以咱們能夠Application中重寫這兩個方法,也能夠在組件中重寫這兩個方法。android

 

先重點介紹一下onTrimMemoryapp

爲了更好的管理內存,OnTrimMemory 方法在 API-14 被引入。這個回調能夠在全部組件中獲取到(ActivityServiceContentProvider, and Application)。ide

你應該根據當前設備的限制複寫 onTrimMemory(int) 來逐步的釋放內存。經過複寫這個方法釋放資源能夠幫助你的app更好的響應系統總體,同時經過讓你的app性能

在系統中存活更久來提升用戶體驗。若是在系統內存很低時,你仍舊不釋放內存,系統將會優先殺死你在的進程。這樣當用戶返回app時須要重啓影響用戶體驗ui

 

onTrimMemory(int)的level值並不成線性關係,它只是提供了內存不一樣狀態的線索。this

1. 回調時機spa

  /**
     * 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.

相關文章
相關標籤/搜索