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

邂逅StringIndexOutOfBoundsException相关推荐

  1. 《OpenCV3编程入门》学习笔记1 邂逅OpenCV

    第1章 邂逅OpenCV 1.1 OpenCV周边概念认知 1.图像处理(Image Processing):计算机对图像进行分析,以达到所需结果的技术,又称影像处理.侧重处理. 2.图像处理技术:图 ...

  2. 知否,知否,交通数据邂逅【数据故事计划二等奖】

    摘要:细听学长学姐讲故事,或许在他们的路上也有你的身影! [第一届数据故事计划] "数据故事计划"旨在收集各类有关大数据的故事然后进行比赛及相关的宣传和推广.包括同学们接触大数据. ...

  3. 案例解读:小红书邂逅AWS,轻松玩转社区+电商

    总有一些公司幸运地,有意识或无意识地站在了技术革命的浪尖之上,也总有一些人在行业的风口以我们意想不到的方式一夜暴富. 近几年,电商成为了财富的代名词,衣食住行所在的领域,电商的触手无孔不入.随之而来的 ...

  4. android 蓝牙 鼠标 app_邂逅甜蜜告白,雷柏ralemo Air 1气垫鼠标,是女生心动的信号_...

    2020年11月02日 09:43作者:陈彤编辑:陈彤文章出处:厂商稿 爱情,到底是什么形状?一颗心?一杯鸡尾酒?一把锁?一个气垫霜? 关于这个问题,雷柏新女性外设系列ralemo,用ralemo A ...

  5. Vue学习(一)-邂逅Vuejs

    Vue学习(一)- 邂逅Vuejs 零.视频链接 一.邂逅Vuejs 1.认识Vuejs 1.1 为什么学习Vuejs 1.2 简单认识一下Vuejs 2.Vuejs安装方式 2.1 CDN引入 2. ...

  6. 【城市沙龙】LiveVideoStack Meet|合肥:在“霸都”邂逅音视频技术

    重启LiveVideoStack Meet后,我们遇到了许多新鲜的面孔,听到了不少有趣又专业的分享.秉持着初心,我们希望给更多二线城市带来零距离的技术交流机会.12月11日,LiveVideoStac ...

  7. (三)HTTP再邂逅--熟悉HTTP协议结构和通讯原理

    HTTP再邂逅--熟悉HTTP协议结构和通讯原理 HTTP协议特点 URL和URI的区别和联系 HTTP报文结构分析 HTTP请求方法剖析 HTTP响应状态码拆解 用telnet分析http协议的通讯 ...

  8. vue 多选自动触发_Vue,初次邂逅(二)

    一.前言 二.Vue常用指令 2.1 什么是指令? 指令 (Directives) 是带有 v- 前缀的特殊特性.指令特性的预期值是:单个 JavaScript 表达式.指令的职责是,当表达式的值改变 ...

  9. 多stream_基础之Lambda和Stream的邂逅

    基础之Lambda和Stream的邂逅 show me the code and take to me,做的出来更要说的明白 GitHub项目JavaHouse同步收录 喜欢就点个赞呗! 你的支持是我 ...

最新文章

  1. django html菜单,django实现动态菜单的方式
  2. ActiveMQ的使用
  3. CMS:文章管理之视图(2)
  4. Quartz Scheduler插件–隐藏的宝藏
  5. mysql附加数据库失败_我的数据库为什么附加不上去?
  6. 问题 A: 百钱买百鸡问题
  7. 如果苹果公司允许其他手机厂商使用iOS系统,对苹果公司来说会有什么好处?
  8. php pdo-insert,php mysql pdo insert multiple rows 批量插入
  9. selenium BY定位
  10. 其实我只想设置客户端实现跨域请求
  11. 泛型列表(List)的搜索和排序
  12. 聚客通微信scrm系统-微信个人号sdk云控方案实现非微信ipad/mac协议
  13. 电机振动噪声(NVH)——整数槽和分数槽谐波分析
  14. Web_制作页面开场动画并解决自动播放问题
  15. 名门正派的设计,与歪门邪道的产品
  16. CPT205 计算机图形 笔记
  17. 再谈搜索已死,推荐上位
  18. 与JDBC相识的第一天超级NICE
  19. 【ivp6服务器可通过ivp4网络访问教程】
  20. 七、Android/Linux安全机制简单了解

热门文章

  1. 感叹号挖孔屏稳了!iPhone 14 Pro高清概念图曝光:屏占比创5年最高
  2. 贾跃亭又造假,250亿灰飞烟灭!
  3. 最早将于Q3季度发布,小米12至尊版将搭载骁龙8 Plus
  4. 华为Mate50渲染图曝光:经典奥利奥相机模组
  5. 腾讯或于本周正式宣布合并搜狗?官方回应:看点招聘及搜狗合并均正常进行...
  6. 岚图FREE店内静态体验
  7. “李国庆午餐1小时”12.94万成交!同时对家暴非常自责
  8. 小米全新5G旗舰手机即将登场 售价必将再创新高
  9. 佛系听歌?Beats推出“串珠”耳机 盘它?
  10. 提效80%|一次【Jmeter】实践的接口自动化