StringBuilder的toString方法,stringbuilder
分享于 点击 43601 次 点评:212
StringBuilder的toString方法,stringbuilder
前几天发布应用出现了点问题,排查过程中同事发在群里一篇文章,仔细看了一下,还是挺有意思的,于是自己模拟了一下场景,
原文在这里,一次简单致命的错误:http://www.blogjava.net/xylz/archive/2012/03/15/371966.html
在频繁的进行字符串的操作增加的时候,我们会优先考虑使用StringBuilder和StringBuffer,其中StringBuffer是线程安全的。有个小地方需要慎重,就是toString()方法。
先看这段代码://读取文件,然后在文件的末尾追加一些特殊字符然后换行
Java代码- public static void main(String[] args) throws Exception {
- BufferedReader reader = new BufferedReader(
- new FileReader("E:\\java_tools\\hatrix1.28\\hatrix.log"));
- StringBuilder sb = new StringBuilder();
- String str = null;
- while((str=reader.readLine())!=null){
- if(StringUtils.isNotEmpty(sb.toString())){
- sb.append("$$$$$$$$\r");
- }
- sb.append(str);
- }
- System.out.println(sb.toString());
- }
上面标红的这里,在小应用或者数据量不大的情况下完全没有问题,但是在数据量大,并且并发多的时候,就会出现问题。
在Stringbuilder的代码中看toString()的代码如下
Java代码
- public String toString() {
- // Create a copy, don't share the array
- return new String(value, 0, count);
- }
每次调用toString方法,会重新new一个String出来。
在java.lang.String的代码中,看最后一行,value并不是直接指向的,而是通过系统拷贝函数进行的内存操作
Java代码- public String(char value[], int offset, int count) {
- if (offset < 0) {
- throw new StringIndexOutOfBoundsException(offset);
- }
- if (count < 0) {
- throw new StringIndexOutOfBoundsException(count);
- }
- // Note: offset or count might be near -1>>>1.
- if (offset > value.length - count) {
- throw new StringIndexOutOfBoundsException(offset + count);
- }
- this.offset = 0;
- this.count = count;
- this.value = Arrays.copyOfRange(value, offset, offset+count);
- }
java.util.Arrays中关于数组拷贝
Java代码
- public static char[] copyOfRange(char[] original, int from, int to) {
- int newLength = to - from;
- if (newLength < 0)
- throw new IllegalArgumentException(from + " > " + to);
- char[] copy = new char[newLength];
- System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
- return copy;
- }
那为啥会通过内存拷贝的形式来进行toString呢,原因在于StringBuilder内部有两个核心的属性,这两个记录了String中的内容,是字符数组的形式。
这时候对于字符数组操作,通过内存拷贝是最快的方式了。
Java代码
- /**
- * The value is used for character storage.
- */
- char value[];
- /**
- * The count is the number of characters used.
- */
- int count;
上述代码中,CPU会一直忙于进行内存的分配工作,会导致机器的load过高
解决办法:
用StringBuilder类中的length来判断是否有数值,这样就避免了无谓的内存操作。
相关文章
- 暂无相关文章
用户点评