<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近看服务器运行的时候,发现CPU使用load特别高,排查了一下,问题出现在下面的代码里面</span>
StringBuilder buf = new StringBuilder(); String line = null; while ((line = br.readLine()) != null) { if (StringUtils.isNotEmpty(buf.toString())) { buf.append("\r\n"); } buf.append(line); }
dump服务器stack的时候,发现代码经常停留在if (StringUtils.isNotEmpty(buf.toString())) 这一行
这是为什么呢?
StringUtils.isNotEmpty是公共方法,应该没什么大问题。
问题就处在buf.toString()上面
public String toString() { // Create a copy, don't share the array return new String(value, 0, count); }
每次toString的时候会新建一个String对象
在看看String的构造方法
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); }
最后一句 Arrays.copyOfRange(value, offset, offset+count);
会不停的拷贝内存,所以内存不高才怪。
其实代码可以不用这么判断,直接判断
StringBuilder buf = new StringBuilder(); String line = null; while ((line = br.readLine()) != null) { if (buf.length()>0) { buf.append("\r\n"); } buf.append(line); }
细节决定成败!理解底层实现原理对于编写高质量代码有很重要的作用!