网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  邂逅stringindexoutofboundsexception     
  文章作者:未知  文章来源:水木森林  
  查看:134次  录入:管理员--2007-11-17  
 
  今天在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。知道这些,我认为够了。




以上来自dayworker的blog,感谢他的总结,希望可以与dayworker成为朋友
 
 
上一篇: 小议如何在application中显示图象    下一篇: 用jdom技术将数据库数据写入读出xml文件
  相关文档
java servlet和jsp教程(7) 11-17
java入门笔记7_stream 11-17
使用actionforward优化struts应用程序 11-16
第一次接触ejb 11-17
在struts中使用validator框架 11-17
实例解析sql server 2000和jdbc的融合 01-14
处理超出打开游标的最大数异常 11-17
对于颓废的程序员我要说:...... 11-17
java容器分析—list和set 11-17
java technology exam objectives 11-17
java开发框架:深入分析jsf与struts的异同 05-13
用java制作网络文件下载系统 11-17
如何使用aop编程减少升级的风险(图) 11-17
java连接数据库谈 11-16
java使用技巧两则---j2ee 1.4简介 11-17
java如何操作word, excel, pdf文档? 11-17
利用java语言实现数据报编程之单播 11-16
[java100例]040、压缩和解压文件 11-17
Eclipse插件开发如虎添翼 03-25
java & xml基础学习笔记 sax篇 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息