<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
    數據加載中……

    StringIndexOutOfBoundException 引出的對String類的看法




    邂逅StringIndexOutOfBoundsException

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

    迫使我對它做了一些分析

    首先:
    “不斷的將被選中的字符串加到某一字符串末尾,當長度超過一定量時提示:
    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。
    上面的錯誤是因為
    String.length()<10;
    而你又要取index>=10的字符從而拋出上面異常
    String其實是沒有限制的,而是當String太大了,超過JVM的自身的內存后會拋出
    java.lang.OutOfMemoryError錯誤

    String是沒有長度限制的,而是有JVM的內存限制了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的默認參數執行(我的機器內存是128M)
    java testString
    結果:
    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使用的內存是1M,當String為12M,JVM使用了63M多時
    JVM溢出。

    然后,我們用限制JVM內存大小的參數來執行,限制最大內存5M
    java -mx5m testString
    結果:
    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使用的內存是1M,當String為768k,JVM使用了5M多時
    JVM溢出。

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

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

    設計人員重新設計程序,不致使程序一次載入所有的數據。

    數據可以分割成更小的塊。

    可以為程序分配更多的內存。

    為Java虛擬機提供更多的內存。

    而上面的例子是為虛擬機提供更多的內存

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

    ==================================
    例如上面的程序改用StringBuffer實現,就可以得到極大的改善。
    下面是我改用StringBuffer做的測試:
    注意:程序循環了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;
    }

    }
    }
    }

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



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

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

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

    評論

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

    有兩個錯誤:
    1.java -mx5m testString
    結果:
    JVM MAX MEMORY: 70M 這里應該是7M, 作者可能打字打錯了.

    2.s=s+s; 和 sb.append(s); 明顯是不一樣的操作了.
    前者 假如s="abbbbb", s=s+s, 會成指數增長"abbbbbabbbbb", "abbbbbabbbbbabbbbbabbbbb", ...; 后者只是每次添加"abbbbb", 一開始"abbbbb", "abbbbbabbbbb", "abbbbbabbbbbabbbbb", ...
    2014-05-13 10:10 | kevinleng
    主站蜘蛛池模板: 国产人成亚洲第一网站在线播放| 国产亚洲成av片在线观看| 亚洲欧洲精品视频在线观看| 国产成人免费ā片在线观看老同学 | 亚洲午夜福利精品无码| 日本视频免费观看| 国产精品亚洲综合一区| 国产精品玖玖美女张开腿让男人桶爽免费看 | 亚洲色偷偷综合亚洲AV伊人| 一级毛片无遮挡免费全部| 亚洲人成无码网站久久99热国产| 一级一看免费完整版毛片| 亚洲色精品vr一区二区三区| 国产一级片免费看| 亚洲乱码一二三四区麻豆| 成年女人免费视频播放体验区| 亚洲国产精品精华液| 亚洲不卡AV影片在线播放| 国产精品内射视频免费| 久久亚洲精品无码| 成年免费大片黄在线观看岛国| 亚洲国产欧美日韩精品一区二区三区| 国产成人免费片在线视频观看| 成人免费777777被爆出| 亚洲四虎永久在线播放| 免费观看男人免费桶女人视频 | 亚洲色偷偷偷网站色偷一区| 成人免费a级毛片无码网站入口| 久久免费精品视频| 亚洲小视频在线观看| 97无码免费人妻超级碰碰夜夜| 免费观看亚洲人成网站| 亚洲AV无码精品色午夜果冻不卡| 亚洲免费黄色网址| 一区二区免费在线观看| 亚洲短视频在线观看| 日本中文一区二区三区亚洲| 91av在线免费视频| 三级片免费观看久久| 亚洲图片校园春色| 亚洲爽爽一区二区三区|