运行环境jdk6,在一个解析报文的方法中使用到了String 类中的subString() 方法,很奇诡运行几天之后,内存就溢出了。从网上查了一下,发现 JDK6的String 类中的subString() 方法的确是有问题的。
jdk6 中方法的实现:
public
String substring(
int
beginIndex,
int
endIndex) {
if
(beginIndex <
0
) {
throw
new
StringIndexOutOfBoundsException(beginIndex);
}
if
(endIndex > count) {
throw
new
StringIndexOutOfBoundsException(endIndex);
}
if
(beginIndex > endIndex) {
throw
new
StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return
((beginIndex ==
0
) && (endIndex == count)) ?
this
:
new
String(offset + beginIndex, endIndex - beginIndex, value);
在String类中存在这样三个属性
- value 字符数组,存储字符串实际的内容
- offset 该字符串在字符数组value中的起始位置
- count 字符串包含的字符的长度
验证subString() 内存泄露的程序
import java.util.Arrays;
public class TestString {
public String largeString = new String(new byte[100000]);
String getString() {
return this.largeString.substring(0,2);
}
public static void main(String[] args) {
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
for (int i = 0; i < 1000000; i++) {
TestString gc = new TestString();
list.add(gc.getString());
for(String s:list){
System.out.print(s+"="+i);
}
}
System.out.println("==============");
}
}
运行结果:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:133)
at java.lang.StringCoding.decode(StringCoding.java:173)
at java.lang.StringCoding.decode(StringCoding.java:185)
at java.lang.String.<init>(String.java:570)
at java.lang.String.<init>(String.java:593)
at boce.test.TestString.<init>(TestString.java:7)
at boce.test.TestString.main(TestString.java:21)
内存溢出了。
下面不使用 subString() 方法来截取字符串:
public class TestString {
public String largeString = new String(new byte[100000]);
String getString() {
byte[] b = Arrays.copyOfRange(largeString.getBytes(), 0, 2);
final String s = new String(b);
return s;
// String s = this.largeString.substring(0,2);
// return s;
//new String(this.largeString.substring(0,2));
}
public static void main(String[] args) {
java.util.ArrayList<String> list = new java.util.ArrayList<String>();
for (int i = 0; i < 10000000; i++) {
TestString gc = new TestString();
list.add(gc.getString());
System.out.print(list.get(i)+"="+i);
}
System.out.println("==============");
}
}
没有出现内存溢出的情况