<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ALL is Well!

    敏捷是一條很長的路,摸索著前進著

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      30 隨筆 :: 23 文章 :: 71 評論 :: 0 Trackbacks

    此問題在項目中被發現,經查看JDK源碼(JDK1.6),String類的public String substring(int beginIndex, int endIndex)的實現讓我很意外。

    想重現這個場景很容易,請看代碼。

     1import java.util.ArrayList;
     2import java.util.List;
     3
     4public class LeakTest {
     5    public static void main(Stringargs) {
     6        List<String> handler = new ArrayList<String>();
     7        for(int i = 0; i < 100000; i++{
     8            Huge h = new Huge();
     9            handler.add(h.getSubString(15));
    10        }

    11    }

    12}

    13
    14class Huge {
    15    private String str = new String(new char[100000]);
    16    public String getSubString(int begin, int end) {
    17        return str.substring(begin, end);
    18    }

    19}

    執行此代碼結果:

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

     

    問題就出在Huge類的 getSubString 方法,它調用了String類的substring方法。

    來讓我們看看 substring 類的實現吧,JDK源碼如下:

     1    public String substring(int beginIndex, int endIndex) {
     2    if (beginIndex < 0{
     3        throw new StringIndexOutOfBoundsException(beginIndex);
     4    }

     5    if (endIndex > count) {
     6        throw new StringIndexOutOfBoundsException(endIndex);
     7    }

     8    if (beginIndex > endIndex) {
     9        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
    10    }

    11    return ((beginIndex == 0&& (endIndex == count)) ? this :
    12        new String(offset + beginIndex, endIndex - beginIndex, value);
    13    }

    再讓我們接下來看看 new String(offset + beginIndex, endIndex - beginIndex, value); 的實現:


    1    // Package private constructor which shares value array for speed.
    2    String(int offset, int count, char value[]) {
    3    this.value = value;
    4    this.offset = offset;
    5    this.count = count;
    6    }


    char[] value 數組被共享了。

     

    在我們的main函數里的循環中,每循環一次后,我們希望Huge對象被回收,且釋放它占有的內存。

    但實際上 private String str = new String(new char[100000]); 占有的內存并不會被釋放。

    因為 我們通過 Huge 類的 getSubString 方法得到的 String 對象還存在(存在于handler的列表中),

    它雖然是 length 只有 4 的對象,卻享有著 char[100000] 的空間。

     

    解決方案:

    可以修改Huge 類的 getSubString 方法如下:

    1    public String getSubString(int begin, int end) {
    2        return new String(str.substring(begin, end));
    3    }

    只要再套一個String的構造方法即可。

     

    至于為什么,看看JDK源碼,一看便知了。這里就不貼出來了。

     

     

    唉,以后寫代碼得多多小心啊。


    ----2010年08月27日

    本文為原創,歡迎轉載,轉載請注明出處BlogJava。
    posted on 2010-09-01 12:41 李 明 閱讀(1465) 評論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 亚洲91av视频| 亚洲中文久久精品无码ww16| 亚洲国产人成网站在线电影动漫| 久久精品无码专区免费| 亚洲国产精品无码AAA片| 国产在线观看免费av站| 亚洲国产成人片在线观看无码| 免费毛片在线看不用播放器| 九月丁香婷婷亚洲综合色| 免费成人高清在线视频| 亚洲精品成人久久| 精品久久久久成人码免费动漫| 亚洲成人福利网站| 24小时日本在线www免费的| 亚洲精品乱码久久久久久蜜桃图片| 日本免费网站在线观看| 免费福利在线观看| 久久亚洲精品成人| 曰曰鲁夜夜免费播放视频| 亚洲精品蜜夜内射| 国产成人精品日本亚洲专区61| 久久免费精品视频| 2020天堂在线亚洲精品专区| 免费永久看黄在线观看app| 男女一边摸一边做爽的免费视频| 久久精品国产亚洲麻豆| 大学生一级毛片免费看| 美女18毛片免费视频| 亚洲av无码专区在线播放| 91成人免费在线视频| 国产精品亚洲综合天堂夜夜| 亚洲色偷偷综合亚洲AVYP| 免费三级毛片电影片| 日韩大片免费观看视频播放| 亚洲精品私拍国产福利在线| 免费观看一级毛片| 国产午夜精品久久久久免费视 | 红杏亚洲影院一区二区三区| 无码日韩精品一区二区三区免费 | 亚洲影院在线观看| 免费人成年轻人电影|