应该这么说,如果字符串内空不多,内存损耗不大。
但比如一个字符串里有100万个字符,然后用string.substring()的方法来截取其中的两个字符串,内存会损耗过大,会溢出。因为在string 的原码里面
用到的value是原来的100万,是一个char[]的String的私有属性(上面的这张截图是新的JDK1.7里的String类方法),而在老的jdk里关于new String()的构造方法也是通过
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}
这就让jvm认为了100万仍在复用,GC不会收回老串,这时如果再来个1000次的循环截取,如:
for (int i = 1; i <= 1001; i++) {
String big = new String(1000000);
System.out.println(i);
*****List.add(big.subString(0, i));
}
此时估计i打不了几次,jvm就直接挂了。因为所有的老串无一回收。
解决这个老JDK的问题就是将*****List.add(big.subString(0, i))改成*****List.add(new String(big.substring())) ,让JVM去回收老的字符串。
老的jdk之所以会这么做,是因为gc的效率问题,且这种情况较少,
新的jdk也解决了这个问题
当然,对重新new对象以外,还有一个方式也可以解决,就是big.substring(0, i).intern(),intern方法有局限性,只有在大字符串中截取小字符串,并且原串不再使用时较有效果,它是将substring的内容放到了常量池中,如果过度使用,也会抛异常的。
我是uplady,记得点赞哦~