分享
 
 
 

邂逅StringIndexOutOfBoundsException

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

今天在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。知道这些,我认为够了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有