今天写了一段代码,大致如下文所示,
这段代码,很好理解,就是我们使用正则去匹配, 得到内容,将匹配的东东放到一个Hashset中。
然后尝试运行, 运行一个小时左右,通过Jconsole发现内存消耗很快,使用mat工具将堆内存分析之后,得出就是这个set占用了太多的内存, 对set对象中的string分析,发现了一个问题,
如果一个string 输出是aaaa, 但是这个string的对象里面的value字段并不是4个a的char[], 而是和content的value字段相同,这就是说,outlink里面的value字段是和content里面的value字段是相同长度的char[], 相当于复制了一遍?,只不过outlink变量的offset和count决定了最后outlink是aaaa,而不是content的输出。
不知道,童鞋门到这里看到了什么问题,是的,set表面上是存了一个outlink的内存,实际上set存了一个content的内存,如果content的长度远远大于outlink的话,就出现了上诉的情况。
晚上查查资料,发现在linux环境下7.0.17版本的String不会出现问题,查看源码, 发现这个版本的String remove掉了count和offset字段,为什么remove掉呢, 肯定不是因为我的原因,官方解释link:
[url]http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-May/010257.html[/url]
好了,事情到了这一步,应该是万事大吉了,
如果是以前版本的话,我这么写了以下,虽然看上去怪怪的,但是总比内存泄露好阿!
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.match(content);//注意这里的content变量
while (matcher.find()) {
String outlink = matcher.group(1);
set.add(outlink);//其中set 是HashSet的类型
}
这段代码,很好理解,就是我们使用正则去匹配, 得到内容,将匹配的东东放到一个Hashset中。
然后尝试运行, 运行一个小时左右,通过Jconsole发现内存消耗很快,使用mat工具将堆内存分析之后,得出就是这个set占用了太多的内存, 对set对象中的string分析,发现了一个问题,
如果一个string 输出是aaaa, 但是这个string的对象里面的value字段并不是4个a的char[], 而是和content的value字段相同,这就是说,outlink里面的value字段是和content里面的value字段是相同长度的char[], 相当于复制了一遍?,只不过outlink变量的offset和count决定了最后outlink是aaaa,而不是content的输出。
不知道,童鞋门到这里看到了什么问题,是的,set表面上是存了一个outlink的内存,实际上set存了一个content的内存,如果content的长度远远大于outlink的话,就出现了上诉的情况。
晚上查查资料,发现在linux环境下7.0.17版本的String不会出现问题,查看源码, 发现这个版本的String remove掉了count和offset字段,为什么remove掉呢, 肯定不是因为我的原因,官方解释link:
[url]http://mail.openjdk.java.net/pipermail/core-libs-dev/2012-May/010257.html[/url]
好了,事情到了这一步,应该是万事大吉了,
如果是以前版本的话,我这么写了以下,虽然看上去怪怪的,但是总比内存泄露好阿!
String link = new String(matcher.group(1).getByte());