`
yingyingol
  • 浏览: 746018 次
文章分类
社区版块
存档分类
最新评论

邂逅StringIndexOutOfBoundsException

 
阅读更多
今天在WCS的测试中邂逅了这个从未接触的exception

迫使我对它做了一些分析


首先:
“不断的将被选中的字符串加到某一字符串末尾,当长度超过一定量时提示:
java.lang.StringIndexOutOfBoundsException:Stringindexoutofrange:10
”并不能说明String有长度限制

JavaAPI指出StringIndexOutOfBoundsException异常
ThrownbyStringmethodstoindicatethatanindexiseithernegativeorgreaterthanthesizeofthestring.ForsomemethodssuchasthecharAtmethod。
上面的错误是因为
String.length()<10;
而你又要取index>=10的字符从而抛出上面异常
String其实是没有限制的,而是当String太大了,超过JVM的自身的内存后会抛出
java.lang.OutOfMemoryError错误

String是没有长度限制的,而是有JVM的内存限制了String的长度

在dayworker的blog中还提到

quote:


publicclasstestString{
publicstaticvoidmain(Stringargs[])
{
Strings="abbbbb";
System.out.println("JVMMAXMEMORY:"+Runtime.getRuntime().maxMemory()/1024/1024+"M");
System.out.println("JVMISUSINGMEMORY:"+Runtime.getRuntime().totalMemory()/1024/1024+"M");
Runtime.getRuntime().traceMethodCalls(true);
while(true)
{
try{
s=s+s;

}catch(Exceptione)
{
System.out.println(e);
}
catch(Erroro)
{Stringunit=null;
intsizeb=s.length();
intsize=sizeb;
inttime=0;
while(size>1024)
{
size=size/1024;
time++;
}
switch(time)
{
case0:unit="byte";break;
case1:unit="k";break;
case2:unit="M";break;
default:unit="byte";
}

System.out.println("Stringhasusedmemory:"+size+unit);
System.out.println("JVMISUSINGMEMORY:"+(float)Runtime.getRuntime().totalMemory()/1024/1024+"M");
System.out.println("MemoryError:"+o);
break;
}

}
}
}
然后我们用JVM的默认参数执行(我的机器内存是128M)
javatestString
结果:
JVMMAXMEMORY:128M
JVMISUSINGMEMORY:1M
Stringhasusedmemory:12M
JVMISUSINGMEMORY:63.5625M
MemoryError:java.lang.OutOfMemoryError
开始JVM使用的内存是1M,当String为12M,JVM使用了63M多时
JVM溢出。

然后,我们用限制JVM内存大小的参数来执行,限制最大内存5M
java-mx5mtestString
结果:
JVMMAXMEMORY:70M
JVMISUSINGMEMORY:1M
Stringhasusedmemory:768.0k
JVMISUSINGMEMORY: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用chararray实现,就肯定由长度限制的,不能用memory来衡量

==================================
例如上面的程序改用StringBuffer实现,就可以得到极大的改善。
下面是我改用StringBuffer做的测试:
注意:程序循环了2097150次!
是使用String的程序的99864倍!

publicclassTestStringBuffer{
publicstaticvoidmain(Stringargs[])
{
Strings="abbbbb";
StringBuffersb=newStringBuffer(s);
System.out.println("JVMISUSINGMEMORY:"+
(Runtime.getRuntime().totalMemory()/1024/1024)+
"M");
Runtime.getRuntime().traceMethodCalls(true);

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

}catch(Exceptione)
{
System.out.println(e);
}
catch(Erroro)
{
Stringunit=null;
intsize=sb.length();
size*=2;

inttime=0;
while(size>1024)
{
size=size/1024;
time++;
}
switch(time)
{
case0:unit="byte";break;
case1:unit="k";break;
case2:unit="M";break;
default:unit="byte";
}

System.out.println("Looptimes:"+count);
System.out.println("Stringhasusedmemory:"+size+unit);
System.out.println("JVMISUSINGMEMORY:"+
(float)Runtime.getRuntime().totalMemory()/1024/1024+
"M");
System.out.println("MemoryError:"+o);
break;
}

}
}
}

输出结果:
JVMISUSINGMEMORY:1M
Looptimes:2097150
Stringhasusedmemory:23M
JVMISUSINGMEMORY:63.75M
MemoryError:java.lang.OutOfMemoryError



=====================
从另一方面说,如果你要处理的字符串达到百兆甚至上GB,使用String对象,根本没法工作,所以这个问题不需要太多讨论。看一下jdk的源文件,String的长度是String对象的一个成员count,类型是int,不是long,也不是char。知道这些,我认为够了。





以上来自dayworker的blog,感谢他的总结,希望可以与dayworker成为朋友
分享到:
评论

相关推荐

    JSTL详细标签库介绍

    target=_blank&gt;邂逅StringIndexOutOfBoundsException&lt;/A&gt; &lt;LI&gt;&lt;A title="避免在Java中使用Checked Exception" href="http://www.jspcn.net/htmlnews/11049415031711687.html" target=_blank&gt;避免在Java中使用...

    Spring+Hibernate StringIndexOutOfBoundsException String index out解决方法

    Spring+Hibernate运行时所出现的异常Caused by java.lang.StringIndexOutOfBoundsException String index out解决方法

    JCreatorPro3.5

    很好用的东西,没用过的试试。我也是刚刚学习java,希望大家能多多帮助。

    java试验报告之异常处理程序设计

    算术异常ArithmeticException(数组越界ArrayIndexOutOfBoundsException、字符串越界异常StringIndexOutOfBoundsException等)处理程序设计与调试。 三、实验硬件、软件环境 1.PC计算机一台,配置为CPU为P4 2.8G,...

    代码折叠工具 For Eclipse ——修复版

    java.lang.StringIndexOutOfBoundsException: String index out of range: 45 at java.lang.String.charAt(Unknown Source) at com.cb.eclipse.folding.java.calculation.UserDefinedRegionHelper.isSentinel...

    Day18——知识点总结

    1. String类 1.1 比较方式要求 1.2 获取方法 ... StringIndexOutOfBoundsException int indexOf(char ch); int indexOf(String str); int indexOf(char ch, int fromIndex); int indexOf(String str, int fr

    Java中String类方法总结

    StringIndexOutOfBoundsException int indexOf(char ch); int indexOf(String str); int indexOf(char ch, int fromIndex); int indexOf(String str, int fromIndex); 这些方法都是获取指定元素所在的下标位置,...

    String类方法的使用

     获取String字符串中指定下标位置的char类型字符,如果index超出有效范围,StringIndexOutOfBoundsException int indexOf(char ch); int indexOf(String str); int indexOf(char ch, int fromIndex); int indexOf...

    apache-maven-3.0.2-bin

    maven raise an java.lang.StringIndexOutOfBoundsException:217 * [MNG-4941] - PluginDescriptorBuilder doesn't populate expression/default-value fields for mojo parameters * [MNG-4952] - [regression] ...

    Day 18 String和IO流

    Day 18 Author: ScorpioDong ... StringIndexOutOfBoundsException int indexOf(char ch); int indexOf(String str); int indexOf(char ch, int fromIndex); int indexOf(String str, int fromIndex); 这

    javajishujishu

    catch(StringIndexOutOfBoundsException e){ e.getMessage(); } } } public void itemStateChanged(Item arg0) { // TODO Auto-generated method stub arg0.setLabel("状态被改变"); mainForm....

    编译器用Java编写程序

    import java.awt.*; import java.awt.event.*; import java.lang.*; import javax.swing.*; public class Counter extends Frame { //声明三个面板的布局 GridLayout gl1,gl2,gl3;...Button b0,b1,b2,b3,b4,b5,...

    LDAP技术,LDAP学习大全

    LDAP 技术总结 第一章LDAP 有关技术介绍......................................................................................................... 3 第一节X.500 目录服务......................................

Global site tag (gtag.js) - Google Analytics