`
iamzhongyong
  • 浏览: 797467 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

StringBuilder的toString方法

    博客分类:
  • java
 
阅读更多

前几天发布应用出现了点问题,排查过程中同事发在群里一篇文章,仔细看了一下,还是挺有意思的,于是自己模拟了一下场景,

原文在这里,一次简单致命的错误:http://www.blogjava.net/xylz/archive/2012/03/15/371966.html

在频繁的进行字符串的操作增加的时候,我们会优先考虑使用StringBuilderStringBuffer,其中StringBuffer是线程安全的。有个小地方需要慎重,就是toString()方法。

 

先看这段代码://读取文件,然后在文件的末尾追加一些特殊字符然后换行

	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()的代码如下

 

  public String toString() {
        // Create a copy, don't share the array
	return new String(value, 0, count);
    }

 

 每次调用toString方法,会重新new一个String出来。

 

 

在java.lang.String的代码中,看最后一行,value并不是直接指向的,而是通过系统拷贝函数进行的内存操作

 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中关于数组拷贝

 

  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中的内容,是字符数组的形式。

这时候对于字符数组操作,通过内存拷贝是最快的方式了。

 

  /**
     * The value is used for character storage.
     */
    char value[];

    /** 
     * The count is the number of characters used.
     */
    int count; 

 

上述代码中,CPU会一直忙于进行内存的分配工作,会导致机器的load过高

 

解决办法:

 

用StringBuilder类中的length来判断是否有数值,这样就避免了无谓的内存操作。

分享到:
评论

相关推荐

    StringBuilder字符串生成工具

    主要生成StringBuilder 字符串 类似 StringBuilder builder = new StringBuilder(); builder.AppendFormat("&lt;span class=\"navSep\"&gt;&lt;/span&gt;\r\n"); builder.AppendFormat("机构看盘&lt;/a&gt;\r\n"); builder....

    SQL工具(自动生成StringBuilder sb=new StringBuilder())

    自动生成如下格式的SQL语句;很方便哦! StringBuilder sb=new StringBuilder(); sb.Append("SELECT * FROM Table \n"); sb.Append("WHERE A="B" \n"); return sb.ToString();

    Java StringBuffer & StringBuilder.pdf

    一、StringBuffer和StringBuilder的区别是什么? Java中的StringBuffer和StringBuilder类是用于处理字符串的可变对象;...String str = sb.toString(); System.out.println(str); // 输出: Hello World // 在指定位置

    C#中String和StringBuilder的简介与区别

    简介区别 String的缺点是每次字符串变量的内容发生了改变时,都必须重新分配内存...执行完之后,将调用ToString方法把工作区中的内容转换为一个字符串,方便赋给一个字符串变量。这样StringBuilder会提升一些性能。 St

    StringBuilder:Javascript 字符串生成器

    字符串生成器javascript StringBuilder 将选择一种快速的方式来运行字符串连接。 单元测试 var sb = new StringBuilder ( ) ; sb . append ( "a" ) . append ( "b" ) ; sb . appends ( "a" , "b" ) ; console . log ...

    ZString:.NET Core和Unity的零分配StringBuilder

    所有的append方法都是泛型的( Append(T value) )并直接写入缓冲区而不是连接value.ToString T1 〜 T16 AppendFormat( AppendFormat(string format, T1 arg1, ..., T16 arg16)避免拳击的结构参数 也T1 〜 T16的...

    C# 字符串常用方法

    对字符串进行操作的方法实际上返回的是新的字符串 对象。因此,出于性能方面的原因,大量的连接或其他涉及字符串的操作应当用 StringBuilder 类执行,如下所示: System.Text.StringBuilder sb = new System.Text....

    浅析C#中StringBuilder类的高效及与String的对比

    在C#中,在处理字符串拼接的时候,使用StringBuilder的效率会比硬拼接字符串高很多。到底有多高,如下: static void Main( string[] args ) { string str1 = string.Empty; Stopwatch sw1 = new Stopwatch(); ...

    C#中String StringBuilder StringBuffer类的用法

    String和StringBuilder和StringBuffer,这三个都是值得深究一翻的,可能很多人会说,实在不行的话,都全部用StringBuilder,啥...所以建议使用(在把值类型转换为字符串的时候,记得用ToString方法)。所以平时写代码的时

    Java从入门到高级(第一天)

    1.1 toString方法 1.2 equals方法 1.3 String类中的equals方法与Object类中的equals方法的不同点  1.4 StringBuilder类与String类的区别  2. 时间日期类 2.1 Date类 2.2 DateFormat类 2.3 Calendar类 3. System类 ...

    C# OPC 类库

    StringBuilder sb = new StringBuilder(sts.szVendorInfo, 200); sb.AppendFormat(" ver:{0}.{1}.{2}", sts.wMajorVersion, sts.wMinorVersion, sts.wBuildNumber); txtStatus.Text = sb.ToString(); // set ...

    Myeclipse破译

    String dx = new StringBuilder(need).append(LL).append(userId).toString(); int suf = this.decode(dx); String code = new StringBuilder(need).append(String.valueOf(suf)) .toString(); return ...

    asp.net 程序性能优化的七个方面 (c#(或vb.net)程序改进)

    1、使用值类型的ToString方法 在连接字符串时,经常使用”+”号直接将数字添加到字符串中。这种方法虽然简单,也可以得到正确结果,但是由于涉及到不同的数据类型,数字需要通过装箱操作转化为引用类型才可以添加到...

    完善的C#/ASP.NET版DBHelper,配套Model生成器

    StringBuilder sql = new StringBuilder(string.Format(@" select * from BS_Template t where 1=1 ")); if (!string.IsNullOrWhiteSpace(noticeType)) { sql.AppendFormat(" and nt.name like '%{0}%'", ...

    .NET 平台下Web 程序设计

    4.12 实验12 ToString()方法的使用 298 4.12.1 实验目标 298 4.12.2 实验步骤 298 4.13 实验13 将字符串转化为其他类型 300 4.13.1 实验目标 300 4.13.2 实验步骤 300 4.14 实验14 Regex类的使用 302 4.14.1 实验...

    获取文件MD5码

    StringBuilder sb = new StringBuilder(); for (int i = 0; i ; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } catch (Exception ex) { throw new Exception("GetMD5...

    2014最新QQWry.Dat 下载

    return (num.ToString() + "." + num2.ToString() + "." + num3.ToString() + "." + num4.ToString()); } public IpLocation Query(string ip) { IpLocation ipLocation = new IpLocation(); if(string....

    C#实现将汉字转化为2位大写的16进制Unicode的方法

    本文实例讲述了C#实现将汉字转化为2位大写的16进制Unicode的方法。分享给大家供大家参考。具体实现方法如下: 说明: str.ToString(“x”) : 转为1位16进制小写 ...var sb =new StringBuilder(); if (string.

    C# 日期函数 string.Format

    Label1.Text = dt.ToString();//2005-11-5 13:21:25 Label2.Text = dt.ToFileTime().ToString();//127756416859912816 Label3.Text = dt.ToFileTimeUtc().ToString();//127756704859912816 Label4.Text = dt....

    delphi获取Cookie源码.rar

    static extern bool InternetGetCookieEx(string pchUrl, string pchCookieName, StringBuilder pchCookieData, ref System.UInt32 pcchCookieData, int dwFlags, IntPtr lpReserved); private static string ...

Global site tag (gtag.js) - Google Analytics