关于substring的char[]共享

我们知道,对于一个较大的String对象如果从中获取一个子串,jdk默认子串的char[]是共享原串的char[],即子串的char[]是原串的char[]中的一部分,

这样对于一个原串多个子串的情况可以节省很大空间。

但是也正是因为共享,如果一个很大的原串在获取一个很小的子串后,原串不再需要,却因为子串共享了char[]一直不能释放,在很多时候造成相反

的结果,甚至出现性能上的问题:

参见:https://code.google.com/p/mybatis/issues/detail?id=760

要解决这种情况 ,在jdk6中,我们只能在获取子串后重新new一个子串的新串使用,以使原串的char[]不再被引用从而快速释放:

String src = "abcdefghijklmnopqrstuvwxyz1234567890-=";

String sub = src.substring(1,4);

sub = new String(sub);

...................................

use sub

这样的方式代码晦涩,问题难查。jdk7去掉共享,同时jdk7优化了拷贝,利用cpu的simd指令。大部分场景下,jdk7字符串性能是比jdk6好的:

 1950       public String substring(int beginIndex, int endIndex) {
 1951           if (beginIndex < 0) {
 1952               throw new StringIndexOutOfBoundsException(beginIndex);
 1953           }
 1954           if (endIndex > count) {
 1955               throw new StringIndexOutOfBoundsException(endIndex);
 1956           }
 1957           if (beginIndex > endIndex) {
 1958               throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
 1959           }
 1960           return ((beginIndex == 0) && (endIndex == count)) ? this :
 1961               new String(offset + beginIndex, endIndex - beginIndex, value);
 1962       }
时间: 2024-12-26 18:29:48

关于substring的char[]共享的相关文章

Java String 综述

摘要: Java 中的 String类 是我们日常开发中使用最为频繁的一个类,但要想真正掌握的这个类却不是一件容易的事情.本文从 Java 内存模型展开,结合 JDK 中 String 类的源码进行深入分析,特别就 String类与享元模式,String 常量池,String的不可变性,String对象的创建方式,String 与 克隆的问题,String.StringBuffer 和 StringBuilder 的区别等几个方面对其进行详细阐述.总结,力求还原 String类 的真实全貌. 一

Java String 综述(上篇)

摘要: Java 中的 String类 是我们日常开发中使用最为频繁的一个类,但要想真正掌握的这个类却不是一件容易的事情.笔者为了还原String类的真实全貌,先分为上.下两篇博文来综述Java中的String类.笔者从Java内存模型展开,结合 JDK 中 String类的源码进行深入分析,特别就 String类与享元模式,String常量池,String不可变性,String对象的创建方式,String与正则表达式,String与克隆,String.StringBuffer 和 String

atitit.复合变量,也就是类似$$a的变量的原理与实现&#160;java&#160;c#.net&#160;php&#160;js

atitit.复合变量,也就是类似$$a的变量的原理与实现 java c#.net php js 1.1. 复合变量,也就是类似$$a的变量,它会进行两次的解释. 1 1.2. 数据库里面的复合变量1 1.3. 为什么只有php实现了符合变量,因为他的美元符号2 1.4. 符合变量的本质其实就是指针了2 2. 使用java实现符合变量2 2.1. invoke2 2.2. 实现2 3. 参考4 1.1. 复合变量,也就是类似$$a的变量,它会进行两次的解释. 这给PHP带来了非常灵活的动态特性.

java身份证号校验

package com.pt.modules.contract.utils; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.regex.Pattern; public class IdcardValida

sql server 查询当天数据

select * from score_get where substring(Convert(char(10),get_time,112),1,8)='20100325' select * from score_get where get_time between '2010-03-25 00:00:00' and '2010-03-25 23:59:59' select * from score_get where year(get_time) = 2010 and month(get_ti

valid bank money number

一直对这种题比较没把握. 没有思路. i 1,000,000.22 34,333.999 define valid(String s,boolean last,boolean first) 1.先s.trim(); if string==null or string.length==0 return false; 2.String[] t = s.spite(','); 得到几组数. if(t.length()==1)   valid(t[0],t,t) else      for() 关于sp

一道CTF题引发的思考-MySQL的几个特性

0x01   背景 前天在做一道CTF题目时一道盲注题,其实盲注也有可能可以回显数据的,如使用DNS或者HTTP等日志来快速的获取数据,MYSQL可以利用LOAD_FILE()函数读取数据,并向远程DNS主机发送数据信息,此时DNS日志文件中就会有盲注语句的查询结果.这里不做这部分的讨论,只是说下有这种方法,在这道题目中我是使用常规的盲注的方式获取数据的.其中遇到有以下几个问题: 过滤规则的判断与绕过 MySQL的一些少有人总结的特性 手动盲注的繁琐低效 这题确实让我思考了很多,当然还有一些特性

看看如何用C语言解析LRC格式的歌词(下)

接上一篇,接下来将来看看怎么实现lyric.c文件. 嗯,在详细说明每个实现的函数之前,首先要在lyric.c中实现在头文件中声明的一些全局变量的定义.当然,要记得定义指针时应拴住指针到一个合法的位置处.因为一个未初始化的指针可能指向内存中任何一个位置,或许是个合法可访问的位置,又或许是个非法不可访问的位置.所以,为了安全起见,我们应当养成好习惯,即在指针初始化时指向一个确定的位置.具体定义如下: //initialize some global variables. char* lrc_tit

SQLSERVER 差异备份、全备份

--exec BackUPDatabase_LeeHG语句参数说明: -- 示例:exec BackUPDatabase_LeeHG '参数一','参数二','参数三','参数四','参数五',' 参数六' -- 参数一:需要备份数据库的名称 -- 参数二:备份文件存放路径,可以是网络路径 -- 参数三:全备份时间 -- 参数四:全备份时间误差范围(小时) -- 参数五:参数三为网络路径时,访问网络路径的用户名,参数三为本地路径时可输入任意字符. -- 参数六:参数三为网络路径时,访问网络路径的