论坛首页 Java企业应用论坛

优化变成了忧患:String类的split方法引起的内存泄漏

浏览 52647 次
该帖已经被评为精华帖
作者 正文
   发表时间:2010-04-03   最后修改:2010-04-03
这个问题我们也遇到过,但是出发点是String.split方法,引出了两个结论.

1. String.split方法性能低下,原因是每次都需要complie表达式.
2. String的subString方法为了提高性能并没有重新创建char数组,而是使用了原有的char数组,只是指针的位置改了一下而已.这样做本意是为了节约内存,但是在楼主的场景下正好变成了浪费内存

所以这里有两个点需要注意以下,
1.如果你是用String.split,那你最好把它换成Pattern.split.(如果你的表达式每次都不一样就没有办法了)
2.如果用substring一定要清除substring的特征.
0 请登录后投票
   发表时间:2010-04-07  
    以前没遇到过这个问题,不过LZ分析的彻底解决方案也有了。值得学习
0 请登录后投票
   发表时间:2010-04-19  
问题:
本来是为了利用一个池概念来减少内存占用,却因为池塘太大,又没人维护,一个人洗澡也需要一池塘水,而导致浪费。

办法thinking...:
1.注意下这种浪费的场景,防止hold住资源,大部分情况是节省内存场景嘛。
2.如果这种没人维护的池hold住资源,那么我们能不能利用jvm维护的String pool来解决这个问题?String 默认的pool会不会也出现不同的String 共享同一个char []?如果不会,使用String.intern()方法会比再次创建一个新对象来解除hold关系要好的多。
0 请登录后投票
   发表时间:2010-04-20  
String.intern()就再也放不掉了,多数场景下恐怕更危险。
0 请登录后投票
   发表时间:2010-04-20  
忽然想起来我还真用过SPLIT来做过报文解析,不过估计数据量不大没有出问题,所以就没发现到这问题。异常哥确实强大。
0 请登录后投票
   发表时间:2010-04-20  
引用

   String.intern()就再也放不掉了,多数场景下恐怕更危险。


这句话有点费解,String 内置在jvm中的pool是被JVM维护,也是会被GC的。我测试了下。

如果你使用强引用,依然hold住资源,不论是不是pool的String对象,两种情况都释放不了对象。

不知道你提到的危险场景是什么,能举个例子吗?
0 请登录后投票
   发表时间:2010-04-20  
moshalanye 写道
引用

   String.intern()就再也放不掉了,多数场景下恐怕更危险。


这句话有点费解,String 内置在jvm中的pool是被JVM维护,也是会被GC的。我测试了下。

如果你使用强引用,依然hold住资源,不论是不是pool的String对象,两种情况都释放不了对象。

不知道你提到的危险场景是什么,能举个例子吗?

软引用MAP
才可以释放资源
但是在楼主的应用中
释放了数据,数据就错了。
0 请登录后投票
   发表时间:2010-04-20  
你是对的。
试了一下,确实回收了。
我原来想歪了,觉得为了保证唯一得一直保留。
再想一下,没必要在没有引用的时候在池中保留,一样不违反==的规约。

还是觉得没必要用intern来做。
并发的时候还是比较多麻烦的。
0 请登录后投票
   发表时间:2010-04-20  
抛出异常的爱 写道
软引用MAP
才可以释放资源
但是在楼主的应用中
释放了数据,数据就错了。

他说的是String类为intern()维护的那个池是软引。
0 请登录后投票
   发表时间:2010-04-20  
抛哥只是说 软引用MAP可以释放资源,没说String pool是使用的软引用,在String里面,我没看到有String pool的实现,并使用 weak reference
    public native String intern();

已经脱离java类型关键字,不存在weak reference的使用,这个是jvm的实现机制。实现的模式估计要看 jvm 标准了。

lz是使用Map 来存在String ,我的建议只是将存放的String对象关联到 String pool中,一来接触与原来 被split的String对象的关联,再个者使用jvm实现好的池模式节省内存空间。不用你自己去管理的池。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics