学习
实践
活动
专区
工具
TVP
写文章

java中的String、StringBuffer与StringBuilder

背景:一客户反馈产品在使用过程中经常出现卡死、响应时间慢,CPU经常爆满。

经现场初步分析:发现在% Time in GC 占用高达90%,而一般情况下也就一两个百分点。由于GC一直在回收垃圾,所以客户端与服务端连接响应时间长,传输数据慢。

获取dump文件分析线程有好几个线程都在做GC回收工作,其中发现有一个线程执行String.Concat执行了35S,而且还在执行中。所以进一步分析为String.Concat滥用,不断创建新的Sring,导致GC一直在回收。我们继续研究了下这个线程执行的方法参数,看到两个参数,参数1太大,看不全,参数2是一个类似GUID的值,然后更进一步确认进行的应该是字符串连接操作。类似于下面这样:

如果a的值比较大,那么再加b的话就会慢,gc回收也会比较慢。代码反编译后看到这样的代码:

这里产生了成千上万个近8M大小的字符串不断更新,根据线程看出产生了(7887918byte/92=产生了85738个对象)foreach循环了这么多次,所以GC一直在忙于回收新产生的String对象,消耗了大量的资源。

解决方案:用StringBuilder(StringBuffer)代替String.Concat (“+”),调用StringBuilder的Append方法时StringBuilder对象不会复制新的对象,而是生成新的StringBuilder对象,并用里面的orinal指向原来的对象。相当于引用指向所有零散自渡船的地址。StringBuilder类型的对象集合在内存中存储可能不是连续的,是一个链表结构;而String.Concat则不一样,a=a+b 中的=运算符每运算一次总是生成新的对象;另外=运算符也比较耗时,不如StringBuilder.Append效率高。StringBuffer是线程安全的,执行效率比StringBuilder效率低点。

StringBuilder>StringBuffer>String.Concat。

高性能编码非常重要,平常编码看不出什么差别,但是真正运行时却是天壤之别。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180419G0827800?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

关注

腾讯云开发者公众号
10元无门槛代金券
洞察腾讯核心技术
剖析业界实践案例
腾讯云开发者公众号二维码

扫码关注腾讯云开发者

领取腾讯云代金券