注:本文当时写的是基于jdk6或者更早版本;jdk7版本无此问题,但substring操作过多,可能会造成性能问题。
-----------------------------------------------------------------------------------------------------------------------------------
使用以下方法需要注意:
trim()
split()
substring()
实际上,这个很容易造成对整个字符串的引用,从而不回收数据对象。以substring为例
strDate= text.substring(1);
这个strDate将直接引用这个text,而不仅仅是date的字符串,如果text是很长的字符串,或者甚至是文本,那么strDate将间接引用text对象,这显然容易造成内存巨大占用。特别是吧strDate当做Map的key时,那么内存占用将会是巨大的。
上面代码改成
strDate = new String(text.substring(1));
new String方法,将会重新生成String对象,而不是直接引用text对象。
以jsoup为例,jsoup是类似jquery查询方法接口的html/xml解析前,很好用的
public void execute(File f, String encoding) {
logger.debug("正在处理" + f.getName());
try {
Document doc = Jsoup.parse(f, encoding);
Elements elems = doc.select("body >table > tbody > tr[id]");// 选择标签table,属性带id的
for (org.jsoup.nodes.Element elem : elems) {
Stat stat = new Stat();
String id = elem.attr("id");
stat.id = new String(id);// (1)需要特别注意这个new String
// .........................
results.add(stat);
}
} catch (Exception e) {
e.printStackTrace();
}
}
上述代码,如果不用new String的话,那么results引用了stat,每个stat有引用了一个String类型的id,而id是从整个文件,也就是说,每个stat引用了一整个文件,如果results很大,那么整个代码都将是巨大的。
这个类似的情况还包含如下库gson(一个json库,也非常好用),举例如下:
JsonReader reader = new JsonReader(new StringReader(json));
if (token.equals("license")) {
String license = reader.nextString();
data.setLicense(new String(license))
}
如果jsonreader传入的是字符串,那么
data.setLicense(new String(license))//注意这里必须用new String(),这样才不会导致data会引用整个json text,而只是引用final String lincene