String 使用的优化建议

其他 String 使用的优化建议

以上我们描述了在我们的大量文本分析案例中调用 String 的 subString方法导致内存消耗的问题,下面再列举一些其他将导致内存浪费的 String 的 API 的使用:

String 拼接的方法选择

在拼接静态字符串时,尽量用 +,因为通常编译器会对此做优化,如:

 String test = "this " + "is " + "a " + "test " + "string"

编译器会把它视为:

 String test = "this is a test string"

在拼接动态字符串时,尽量用 StringBuffer 或 StringBuilder的 append,这样可以减少构造过多的临时 String 对象。

String 构造的方法选择

常见的创建一个 String 可以用赋值操作符"=" 或用 new 和相应的构造函数。初学者一定会想这两种有何区别,举例如下:

 String a1 = “Hello”;
String a2 = new String(“Hello”);

第一种方法创建字符串时 JVM 会查看内部的缓存池是否已有相同的字符串存在:如果有,则不再使用构造函数构造一个新的字符串,直接返回已有的字符串实例;若不存在,则分配新的内存给新创建的字符串。

第二种方法直接调用构造函数来创建字符串,如果所创建的字符串在字符串缓存池中不存在则调用构造函数创建全新的字符串,如果所创建的字符串在字符串缓存池中已有则再拷贝一份到 Java 堆中。

尽管这是一个简单明显的例子,然而在实际项目中编程者却不那么容易洞察因为这两种方式的选择而带来的性能问题。

使用构造函数 string() 带来的内存性能隐患和缓解

仍然以之前的从 csv 文件中截取 String 为例,先前我们通过用 new String() 去除返回的 String 中附带的原始 String 的方法优化了 subString导致的内存消耗问题。然而,当我们下意识地使用 newString去构造一个全新的字符串而不是用赋值符来创建(重用)一个字符串时,就导致了另一个潜在的性能问题,即:重复创建大量相同的字符串。说到这里,您也许会想到使用缓存池的技术来解决这一问题,大概有如下两种方法:

方法一,使用 String 的 intern()方法返回 JVM 对字符串缓存池里相应已存在的字符串引用,从而解决内存性能问题,但这个方法并不推荐!原因在于:首先,intern() 所使用的池会是 JVM 中一个全局的池,很多情况下我们的程序并不需要如此大作用域的缓存;其次,intern() 所使用的是 JVM heap 中 PermGen 相应的区域,在 JVM 中 PermGen 是用来存放装载类和创建类实例时用到的元数据。程序运行时所使用的内存绝大部分存放在 JVM heap 的其他区域,过多得使用 intern()将导致 PermGen 过度增长而最后返回 OutOfMemoryError,因为垃圾收集器不会对被缓存的 String 做垃圾回收。所以我们建议使用第二种方式。

方法二,用户自己构建缓存,这种方式的优点是更加灵活。创建 HashMap,将需缓存的 String 作为 key 和 value 存放入 HashMap。假设我们准备创建的字符串为 key,将 Map cacheMap 作为缓冲池,那么返回 key 的代码如下:

 private String getCacheWord(String key) {
String tmp = cacheMap.get(key);
if(tmp != null) {
return tmp;
} else {
cacheMap.put(key, key);
return key;
}
}
 

回页首

结束语

本文通过一个实际项目中遇到的因使用 String 而导致的性能问题讲述了 String 在 JVM 中的存储结构,String 的 API 使用可能造成的性能问题以及解决方法。相信这些建议能对处理大文本分析的朋友有所帮助,同时希望文中提到的某些优化方法能被举一反三的应用在其他有关 String 的性能优化的场合。

String性能优化的更多相关文章

  1. Java 性能优化之 String 篇

    原文:http://www.ibm.com/developerworks/cn/java/j-lo-optmizestring/ Java 性能优化之 String 篇 String 方法用于文本分析 ...

  2. Java性能优化之String字符串优化

    字符串是软件开发中最重要的对象之一.通常,字符串对象在内存中是占据了最大的空间块,因此如何高效地处理字符串,必将是提高整体性能的关键所在. 1.字符串对象及其特点 Java中八大基本数据类型没有Str ...

  3. String字符串性能优化的探究

    一.背景 String 对象是我们使用最频繁的一个对象类型,但它的性能问题却是最容易被忽略的.String 对象作为 Java 语言中重要的数据类型,是内存中占用空间最大的一个对象,高效地使用字符串, ...

  4. C#中那些[举手之劳]的性能优化

    隔了很久没写东西了,主要是最近比较忙,更主要的是最近比较懒...... 其实这篇很早就想写了 工作和生活中经常可以看到一些程序猿,写代码的时候只关注代码的逻辑性,而不考虑运行效率 其实这对大多数程序猿 ...

  5. Android性能优化之利用LeakCanary检测内存泄漏及解决办法

    前言: 最近公司C轮融资成功了,移动团队准备扩大一下,需要招聘Android开发工程师,陆陆续续面试了几位Android应聘者,面试过程中聊到性能优化中如何避免内存泄漏问题时,很少有人全面的回答上来. ...

  6. Mysql - 性能优化之子查询

    记得在做项目的时候, 听到过一句话, 尽量不要使用子查询, 那么这一篇就来看一下, 这句话是否是正确的. 那在这之前, 需要介绍一些概念性东西和mysql对语句的大致处理. 当Mysql Server ...

  7. 【腾讯Bugly干货分享】跨平台 ListView 性能优化

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/FbiSLPxFdGqJ00WgpJ94yw 导语 精 ...

  8. CSS3与页面布局学习总结(八)——浏览器兼容与前端性能优化

    一.浏览器兼容 1.1.概要 世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题.不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运 ...

  9. 记录一次bug解决过程:可维护性和性能优化

    一.总结 使用某些变量的地方在2次以上的,强烈建议使用枚举值来维护变量,日后方便扩展. 查数据库的方法调用,能合并就净量去合并. 二.Bug描述 枚举变量的维护以及方法使用: public class ...

随机推荐

  1. 打不开chm文件解决办法

    打不开chm文件解决办法.bat regsvr32 itss.dll /sregsvr32 hhctrl.ocx /s

  2. mysql通过binlog日志来恢复数据

    简介 在生产的过程中有这么一个业务场景:比如我在2016-11-19 09:30:00 通过mysqldump的方式备份了数据库,但是在2016-11-19 10:30:00的时候数据库崩溃了,如果通 ...

  3. 队列中使用Database Driver

    队列允许你将一个耗时的任务进行延迟处理. 首先要在.evn文件中配置 QUEUE_DRIVER=database 要使用 database 这个队列驱动的话,则需要创建一个数据表来记住任务,使用命令: ...

  4. @font-face字体文件用法

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. Azure 云平台用 SQOOP 将 SQL server 2012 数据表导入 HIVE / HBASE

    My name is Farooq and I am with HDinsight support team here at Microsoft. In this blog I will try to ...

  6. Linux下把Mysql和Apache加入到系统服务里

    Linux下注册Apache与MySQL为系统服务 Apache加入到系统服务里面: cp /安装目录下/apache/bin/apachectl /etc/rc.d/init.d/httpd 修改h ...

  7. nyoj------203三国志

    三国志 时间限制:3000 ms  |  内存限制:65535 KB 难度:5  描述 <三国志>是一款很经典的经营策略类游戏.我们的小白同学是这款游戏的忠实玩家.现在他把游戏简化一下,地 ...

  8. 使用Node.js实现数据推送

    业务场景:后端更新数据推送到客户端(Java部分使用Tomcat服务器). 后端推送数据的解决方案有很多,比如轮询.Comet.WebSocket. 1. 轮询对于后端来说开发成本最低,就是按照传统的 ...

  9. JDE客户端get时报错“ERROR:fetch from table F0101 failed”

    客户端开发时发现总报错误“ERROR:fetch from table F0101 failed” 原因是用户ID在地址名册中找不到地址号.修改用户地址号即可.如下图所示

  10. C#语法小用法

    数据在存为数据库之前,用JS的encodeURIComponent进行编码,现需要在后台代码中进行解码,实现decodeURIComponent的功能, 如下: HttpUtility.UrlDeco ...