免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1540 | 回复: 0
打印 上一主题 下一主题

邂逅StringIndexOutOfBoundsException [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-03-30 17:59 |只看该作者 |倒序浏览

今天在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的字符从而抛出上面异常
String其实是没有限制的,而是当String太大了,超过JVM的自身的内存后会抛出
java.lang.OutOfMemoryError错误
String是没有长度限制的,而是有JVM的内存限制了String的长度
在dayworker的blog中还提到
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。知道这些,我认为够了。
以上来自dayworker的blog,感谢他的总结,希望可以与dayworker成为朋友


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/18/showart_18583.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP