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

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

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

    海闊天空

    I'm on my way!
    隨筆 - 17, 文章 - 69, 評論 - 21, 引用 - 0
    數(shù)據(jù)加載中……

    StringIndexOutOfBoundException 引出的對String類的看法




    邂逅StringIndexOutOfBoundsException

    今天在WCS的測試中邂逅了這個(gè)從未接觸的exception

    迫使我對它做了一些分析

    首先:
    “不斷的將被選中的字符串加到某一字符串末尾,當(dāng)長度超過一定量時(shí)提示:
    java.lang.StringIndexOutOfBoundsException: String index out of range: 10
    ”并不能說明String有長度限制

    Java API指出StringIndexOutOfBoundsException異常
    Thrown by String methods to indicate that an index is either negative or greater than the size of the string. For some methods such as the charAt method。
    上面的錯(cuò)誤是因?yàn)?br /> String.length()<10;
    而你又要取index>=10的字符從而拋出上面異常
    String其實(shí)是沒有限制的,而是當(dāng)String太大了,超過JVM的自身的內(nèi)存后會拋出
    java.lang.OutOfMemoryError錯(cuò)誤

    String是沒有長度限制的,而是有JVM的內(nèi)存限制了String的長度

    在dayworker的blog中還提到

    [quote]

    public class testString{
    public static void main(String args[])
    {
    String s="abbbbb";
    System.out.println("JVM MAX MEMORY: "+Runtime.getRuntime().maxMemory()/1024/1024+"M");
    System.out.println("JVM IS USING MEMORY:"+Runtime.getRuntime().totalMemory()/1024/1024+"M");
    Runtime.getRuntime().traceMethodCalls(true);
    while(true)
    {
    try{
    s=s+s;

    }catch(Exception e)
    {
    System.out.println(e);
    }
    catch(Error o)
    { String unit = null;
    int sizeb = s.length();
    int size = sizeb;
    int time = 0;
    while(size>1024)
    {
    size = size/1024;
    time++;
    }
    switch(time)
    {
    case 0: unit = "byte";break;
    case 1: unit = "k"; break;
    case 2: unit = "M"; break;
    default : unit = "byte";
    }

    System.out.println("String has used memory:"+size+unit);
    System.out.println("JVM IS USING MEMORY:"+(float)Runtime.getRuntime().totalMemory()/1024/1024+"M");
    System.out.println("MemoryError:"+o);
    break;
    }

    }
    }
    }
    然后我們用JVM的默認(rèn)參數(shù)執(zhí)行(我的機(jī)器內(nèi)存是128M)
    java testString
    結(jié)果:
    JVM MAX MEMORY: 128M
    JVM IS USING MEMORY:1M
    String has used memory:12M
    JVM IS USING MEMORY:63.5625M
    MemoryError:java.lang.OutOfMemoryError
    開始JVM使用的內(nèi)存是1M,當(dāng)String為12M,JVM使用了63M多時(shí)
    JVM溢出。

    然后,我們用限制JVM內(nèi)存大小的參數(shù)來執(zhí)行,限制最大內(nèi)存5M
    java -mx5m testString
    結(jié)果:
    JVM MAX MEMORY: 70M
    JVM IS USING MEMORY:1M
    String has used memory:768.0k
    JVM IS USING MEMORY:5.9375M
    MemoryError:java.lang.OutOfMemoryError
    開始JVM使用的內(nèi)存是1M,當(dāng)String為768k,JVM使用了5M多時(shí)
    JVM溢出。

    大家還可以改變 -mx參數(shù),來進(jìn)一步做實(shí)驗(yàn)。
    以上兩個(gè)實(shí)驗(yàn)證明,String是沒有長度限制的,而是有JVM的內(nèi)存限制了String的長度。同時(shí)說明,并不會拋出任何Exception而只會拋出Error.

    OutMemoryError表明程序的設(shè)計(jì)很差,或者遇到了超出編程人員所預(yù)想的大批量的數(shù)據(jù)。不管哪種情況,都只有下面這幾種解決辦法。它們是:

    設(shè)計(jì)人員重新設(shè)計(jì)程序,不致使程序一次載入所有的數(shù)據(jù)。

    數(shù)據(jù)可以分割成更小的塊。

    可以為程序分配更多的內(nèi)存。

    為Java虛擬機(jī)提供更多的內(nèi)存。

    而上面的例子是為虛擬機(jī)提供更多的內(nèi)存

    =======================================
    其實(shí)應(yīng)該少用String這東西,特別是 String的 +=操作
    不僅原來的String對象不能繼續(xù)使用,主要是又要new出N多的新對象出來,再多的memory也要out~~
    String用char array實(shí)現(xiàn),就肯定由長度限制的,不能用memory來衡量

    ==================================
    例如上面的程序改用StringBuffer實(shí)現(xiàn),就可以得到極大的改善。
    下面是我改用StringBuffer做的測試:
    注意:程序循環(huán)了2097150次!
    是使用String的程序的99864倍!

    public class TestStringBuffer{
    public static void main(String args[])
    {
    String s="abbbbb";
    StringBuffer sb = new StringBuffer(s);
    System.out.println("JVM IS USING MEMORY:"+
    (Runtime.getRuntime().totalMemory()/1024/1024)+
    "M");
    Runtime.getRuntime().traceMethodCalls(true);

    int count = 0;
    while(true)
    {
    try{
    sb.append(s);
    count++;

    }catch(Exception e)
    {
    System.out.println(e);
    }
    catch(Error o)
    {
    String unit = null;
    int size = sb.length();
    size *= 2;

    int time = 0;
    while(size>1024)
    {
    size = size/1024;
    time++;
    }
    switch(time)
    {
    case 0: unit = "byte";break;
    case 1: unit = "k"; break;
    case 2: unit = "M"; break;
    default : unit = "byte";
    }

    System.out.println("Loop times:"+count);
    System.out.println("String has used memory:"+size+unit);
    System.out.println("JVM IS USING MEMORY:"+
    (float)Runtime.getRuntime().totalMemory()/1024/1024+
    "M");
    System.out.println("MemoryError:"+o);
    break;
    }

    }
    }
    }

    輸出結(jié)果:
    JVM IS USING MEMORY:1M
    Loop times:2097150
    String has used memory:23M
    JVM IS USING MEMORY:63.75M
    MemoryError:java.lang.OutOfMemoryError



    =====================
    從 另一方面說,如果你要處理的字符串達(dá)到百兆甚至上GB,使用String對象,根本沒法工作,所以這個(gè)問題不需要太多討論??匆幌耲dk的源文 件,String的長度是String對象的一個(gè)成員count,類型是int,不是long,也不是char。知道這些,我認(rèn)為夠了

    摘自:http://blog.chinaunix.net/u/18/showart_18583.html

    posted on 2009-08-12 16:15 石頭@ 閱讀(18375) 評論(1)  編輯  收藏 所屬分類: java_base

    評論

    # re: StringIndexOutOfBoundException 引出的對String類的看法[未登錄]  回復(fù)  更多評論   

    有兩個(gè)錯(cuò)誤:
    1.java -mx5m testString
    結(jié)果:
    JVM MAX MEMORY: 70M 這里應(yīng)該是7M, 作者可能打字打錯(cuò)了.

    2.s=s+s; 和 sb.append(s); 明顯是不一樣的操作了.
    前者 假如s="abbbbb", s=s+s, 會成指數(shù)增長"abbbbbabbbbb", "abbbbbabbbbbabbbbbabbbbb", ...; 后者只是每次添加"abbbbb", 一開始"abbbbb", "abbbbbabbbbb", "abbbbbabbbbbabbbbb", ...
    2014-05-13 10:10 | kevinleng
    主站蜘蛛池模板: WWW国产亚洲精品久久麻豆| 国产拍拍拍无码视频免费| 亚洲av午夜精品一区二区三区| 一级毛片在线免费播放| 亚洲第一福利网站| 四虎成人免费观看在线网址| 中文永久免费观看网站| 亚洲人成电影网站| 国产亚洲欧洲Aⅴ综合一区| 手机看黄av免费网址| 一级特黄a免费大片| 亚洲国产成人精品青青草原| 亚洲第一永久AV网站久久精品男人的天堂AV | 国产h肉在线视频免费观看| 偷自拍亚洲视频在线观看99| 亚洲人成电影在线天堂| www国产亚洲精品久久久| 3344永久在线观看视频免费首页| 美女黄频视频大全免费的| 亚洲综合男人的天堂色婷婷| 亚洲第一区精品日韩在线播放| 免费看片在线观看| 巨胸喷奶水www永久免费| 亚洲一本一道一区二区三区| 亚洲AV无码日韩AV无码导航| 一区国严二区亚洲三区| 啦啦啦中文在线观看电视剧免费版 | 爽爽爽爽爽爽爽成人免费观看| 亚洲www77777| 亚洲无删减国产精品一区| 亚洲片国产一区一级在线观看 | 亚洲av无码成人黄网站在线观看 | 午夜神器成在线人成在线人免费 | 免费看男人j放进女人j免费看| 国产亚洲欧美日韩亚洲中文色| 亚洲精品中文字幕无乱码| 久久国产亚洲精品麻豆| 亚洲婷婷国产精品电影人久久| 卡1卡2卡3卡4卡5免费视频| 久视频精品免费观看99| a级毛片免费播放|