<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
    主站蜘蛛池模板: 精品久久久久久亚洲中文字幕| 亚洲人成网站影音先锋播放| 自拍日韩亚洲一区在线| 少妇太爽了在线观看免费视频| 亚洲国产精品无码中文字| 国产在线播放线91免费| 亚洲一区二区女搞男| 在线免费视频你懂的| 亚洲av综合av一区| 一级毛片aaaaaa免费看| 亚洲视频日韩视频| 无限动漫网在线观看免费 | 无人在线观看免费高清视频| 亚洲白嫩在线观看| 久久天天躁狠狠躁夜夜免费观看| 亚洲不卡中文字幕| 国外成人免费高清激情视频| mm1313亚洲国产精品无码试看| 亚洲&#228;v永久无码精品天堂久久| 美女又黄又免费的视频| 国产亚洲精品a在线观看 | 色片在线免费观看| 91在线亚洲综合在线| 免费乱理伦在线播放| 毛片基地看看成人免费| 7777久久亚洲中文字幕蜜桃| 四虎成年永久免费网站| 亚洲国产精品精华液| 亚洲午夜福利精品久久| 日本免费在线观看| 国产99在线|亚洲| 亚洲黄黄黄网站在线观看| 国产日韩AV免费无码一区二区| 亚洲美免无码中文字幕在线| 欧洲精品免费一区二区三区| h视频在线免费观看| 亚洲无砖砖区免费| 亚洲成A人片在线观看中文| 国产va在线观看免费| 亚洲熟女乱色一区二区三区| 国产亚洲av人片在线观看|