Java中List集合中subList的坑

來源:互聯網
上載者:User

標籤:sublist   for   nts   cee   引用   over   rom   try   方法   

參考博主http://blog.csdn.net/xuweilinjijis/article/details/9037635

先看List介面subList方法的javadoc 

 The returned list is backed by this list, so non-structural
* changes in the returned list are reflected in this list, and vice-versa.
* The returned list supports all of the optional list operations supported
* by this list.
可以看到此方法其實就是直接指向原List集合中的元素,只是改變了開始位置和結束為止而已.如果修改返回對象的資料,那麼原對象對應的值也會被修改。
看一下List介面具體實作類別 ArrayList類,其中的subList方法源碼如下
public List<E> subList(int fromIndex, int toIndex) {        subListRangeCheck(fromIndex, toIndex, size);//檢查是否越界        return new SubList(this, 0, fromIndex, toIndex);//返回截取之後的對象    }

 再接著看一下 SubList類的構造器,JDK源碼如下,其實 SubList就是ArrayList中的一個內部類(非靜態),

 private class SubList extends AbstractList<E> implements RandomAccess {        private final AbstractList<E> parent;//引用調用的父集合        private final int parentOffset;//父集合的起始位置        private final int offset;//原對象的起始位置        int size;//現在集合的大小        SubList(AbstractList<E> parent,                int offset, int fromIndex, int toIndex) {            this.parent = parent;//從此處可以看到父集合一直被子集合引用著,只要子集合存在,父集合就不會被釋放。從而容易造成記憶體溢出            this.parentOffset = fromIndex;            this.offset = offset + fromIndex;            this.size = toIndex - fromIndex;            this.modCount = ArrayList.this.modCount;        }}

  下面是一段造成記憶體溢出的代碼

 List<List<Integer>> cache = new ArrayList<List<Integer>>();        try {            while (true) {                ArrayList<Integer> list = new ArrayList<>();                for(int j=0;j<100000;j++) {                    list.add(j);                }                List<Integer> subList = list.subList(0, 1);                cache.add(subList);            }        } catch (Exception e) {        }finally {            System.out.println("Cache Size=" + cache.size());        }

  運行結果

      Exception in thread "main" Cache Size=815
      java.lang.OutOfMemoryError: GC overhead limit exceeded
     at java.lang.Integer.valueOf(Integer.java:832)
    at com.effectJava.Chapter2.InstrumentedHashSet.main(InstrumentedHashSet.java:44)

看到只包含815個元素就記憶體溢出啦。就是因為子物件一隻引用著父物件,導致父物件無法回收。從而記憶體溢出

 

     




Java中List集合中subList的坑

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.