Android記憶體最佳化:ArrayMap

來源:互聯網
上載者:User

標籤:

通常我們在使用key-value儲存資料時,隨手就會打出HashMap的代碼,當資料量較小時,還可以,當數量比較多的時候,如果是PC機上,也還說得過去,但是如果使用裝置是手機等行動裝置,這是就要謹慎了。因為手機的記憶體非常寶貴,不像PC那樣不計後果的使用,記憶體使用量不當很容易就會引起OOM的問題。那AndroidTeam Dev,也為我們找到了HashMap的替代品ArrayMap。

官方對ArrayMap也有說明:它不是一個適應大資料的資料結構,相比傳統的HashMap速度要慢,因為尋找方法是二分法,並且當你刪除或者添加資料時,會對空間重新調整,在使用大量資料時,效率並不明顯,低於50%。

所以ArrayMap是犧牲了時間換區空間。在寫手機app時,適時的使用ArrayMap,會給記憶體使用量帶來可觀的提升。

那HashMap和ArrayMap到底不同在哪呢,個人總結有以下方面:

1、儲存方式不同。

HashMap內部有一個HashMapEntry<K, V>[]對象,每一個索引值對都儲存在這個對象裡,當使用put方法添加索引值對時,就會new一個HashMapEntry對象

    @Override public V put(K key, V value) {        if (key == null) {            return putValueForNullKey(value);        }        int hash = secondaryHash(key);        HashMapEntry<K, V>[] tab = table;        int index = hash & (tab.length - 1);//先尋找有沒有對應的key值,如果有,就改寫value,並返回改寫前的value值:oldValue        for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {            if (e.hash == hash && key.equals(e.key)) {                preModify(e);                V oldValue = e.value;                e.value = value;                return oldValue;            }        }        // No entry for (non-null) key is present; create one        modCount++;        if (size++ > threshold) {//擴容,雙倍            tab = doubleCapacity();            index = hash & (tab.length - 1);        }        addNewEntry(key, value, hash, index);        return null;    }//建立Object Storage Service索引值對    void addNewEntry(K key, V value, int hash, int index) {        table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]);    }

ArrayMap的儲存中沒有Entry這個東西,他是由兩個數組來維護的

    int[] mHashes;    Object[] mArray;
mHashes數組中儲存的是每一項的HashCode值,mArray中就是索引值對,每兩個元素代表一個索引值對,前面儲存key,後面的儲存value,我們看看下面代碼的結果

arraymap = new HashMap<String, String>();a.put("a", "a_value");a.put("b", "b_value");
執行上面代碼後,arraymap中的儲存是這樣的

是不是能清楚地看到ArrayMap的儲存了,這種儲存在put代碼中如下

        mHashes[index] = hash;        mArray[index<<1] = key;        mArray[(index<<1)+1] = value;

2、添加資料時擴容時的處理不一樣

先來看看HashMap

        if (size++ > threshold) {            tab = doubleCapacity();            index = hash & (tab.length - 1);        }
doubleCapacity進行雙倍擴容,它的代碼中有這麼一句話

HashMapEntry<K, V>[] newTable = makeTable(newCapacity);
最終,這個newTable將作為擴容後的新對象返回,那麼makeTable做了什麼呢,如下:

    private HashMapEntry<K, V>[] makeTable(int newCapacity) {        @SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable                = (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity];        table = newTable;        threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity        return newTable;    }
我們清楚地看到,這裡進行了new操作,重新建立對象,開銷很大。

那麼ArrayMap呢,看看吧

        //如果容量不夠if (mSize >= mHashes.length) {            final int n = mSize >= (BASE_SIZE*2) ? (mSize+(mSize>>1))                    : (mSize >= BASE_SIZE ? (BASE_SIZE*2) : BASE_SIZE);            if (DEBUG) Log.d(TAG, "put: grow from " + mHashes.length + " to " + n);            final int[] ohashes = mHashes;            final Object[] oarray = mArray;        //分配數組            allocArrays(n);            if (mHashes.length > 0) {                if (DEBUG) Log.d(TAG, "put: copy 0-" + mSize + " to 0");                //特別注意這,是copy,而不是new,效率提升                System.arraycopy(ohashes, 0, mHashes, 0, ohashes.length);                System.arraycopy(oarray, 0, mArray, 0, oarray.length);            }                //釋放無用空間,收縮數組            freeArrays(ohashes, oarray, mSize);        }


ArrayMap用的是copy資料,所以效率相對要高。

3、ArrayMap提供了數組收縮的功能,在clear或remove後,會重新收縮數組,是否空間

4、ArrayMap採用二分法尋找(見 android.support.v4.util.ContainerHelpers中的binarySearch方法)






著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android記憶體最佳化:ArrayMap

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.