(转)Java中字符串与内存泄漏的问题

标签: java 字符串 内存泄漏 | 发表时间:2013-05-06 21:31 | 作者:
出处:http://jackyrong.iteye.com
http://clarkht.iteye.com/blog/482644

String oldStr = "hello,clark"; 
String newStr = oldStr.subString(0,4);  
对于这个写法,实际上对于oldStr是一个char[]数组[h,e,l,l,0,,,c,l,a,r,k],对于subString操作,newStr并不是自己copy oldStr的char[]数组hello自己去创建一个新的char[]数组,而是java在背后进行了String Reusing Optimization,它不会自己创建一个新的char数组,而是reuse原来的char数组。所以了,这样就不会有很多的原来的char[]数组的碎片。引用http://www.javablogging.com/string-and-memory-leaks/ 上的列子:
Java代码 
public static void sendEmail(String emailUrl) { 
    String email = emailUrl.substring(7); // 'mailto:' prefix has 7 letters 
    String userName = email.substring(0, email.indexOf("@")); 
    String domainName = email.substring(email.indexOf("@")); 

 
public static void main(String[] args) { 
    sendEmail("mailto:[email protected]_name.com"); 
}  


但是这个虽然在一般情况是好,不过也是有代价的。根据http://nflath.com/2009/07/the-dangers-of-stringsubstring/上,因为字符串不是自己新建一个char[]数组,而是引用了原来的char[]数组,这样oldStr就无法garbage collected ,因为newStr还是拥有oldStr的char[]数组的引用。这样容易引起Outof Memory 异常。解决办法是了,便是让newStr拥有自己的char[]数组,也就是自己在subString时强迫创建自己的char[]数组,这样就不会有garbage collected 的问题(reachable but unused!) 怎么办:                                           
Java代码 
String sub = new String( oldString.substring(0, 4) ); 


---------------------------------------------------------------
为了避免内存拷贝、加快速度,Sun JDK直接复用了原String对象的char[],偏移量和长度来标识不同的字符串内容。也就是说,subString出的来String小对象仍然会指向原String大对象的char[],split也是同样的情况 。这就解释了,为什么HashMap中String对象的char[]都那么大。

-------------------------------------------------------
可以参考:
http://jarfield.iteye.com/blog/583946


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [java 字符串 内存泄漏] 推荐:

(转)Java中字符串与内存泄漏的问题

- - jackyrong
对于这个写法,实际上对于oldStr是一个char[]数组[h,e,l,l,0,,,c,l,a,r,k],对于subString操作,newStr并不是自己copy oldStr的char[]数组hello自己去创建一个新的char[]数组,而是java在背后进行了String Reusing Optimization,它不会自己创建一个新的char数组,而是reuse原来的char数组.

java内存泄漏

- - 编程语言 - ITeye博客
不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址. Java中对象是采用new或者反射的方法创建的,这些对象的创建都是在堆(Heap)中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的. GC为了能够正确释放对象,会监控每个对象的运行状况,对他们的申请、引用、被引用、赋值等状况进行监控,Java会使用有向图的方法进行管理内存,实时监控对象是否可以达到,如果不可到达,则就将其回收,这样也可以消除引用循环的问题.

浅谈Java--内存泄漏

- - ITeye博客
      JAVA的垃圾回收机制,让许多程序员觉得内存管理不是很重要,但是内存内存泄露的事情恰恰这样的疏忽而发生,特别是对于Android开发,内存管理更为重要,养成良好的习惯,有利于避免内存的泄漏..     这里可以把许多对象和引用看成是有向图,顶点可以是对象也可以是引用,引用关系就是有向边.

JAVA内存泄漏问题处理方法经验总结

- - 编程语言 - ITeye博客
JVM问题,一般会有三种情况,目前遇到了两种,线程溢出和JVM不够用. 1.线程溢出:unable to create new native thread. 系统在1月4号左右,突然发现会产生内存溢出问题,从日志上看,错误信息为:. 导致系统不能使用,对外不能相应,但是观察gc等又处于正常情况,free 系统内存也正常.

判断字符串是否是有效json对象(java + gson )

- - 改善
已有 0 人发表留言,猛击->> 这里<<-参与讨论. —软件人才免语言低担保 赴美带薪读研.

字符串匹配 KMP 算法 Java实现

- - ITeye博客
字符串匹配过程中,如果使用蛮力算法,效率非常的差,在此介绍一种较为高效的匹配算法KMP算法. 其主要思想是从匹配的模版去分析,即去分析Pattern串的自身规律,进而去优化匹配的效率. 例如字符串“ababcb”,明显看出是ab出现一组重复,若出现如下匹配模式:. 此时发生错误,一般情况下会选择移动Pattern一个位置来继续,事实证明效果不佳.

Java字符串的10大热点问题盘点

- - 极客521 | 极客521
下面我为大家总结了10条Java开发者经常会提的关于Java字符串的问题,如果你也是Java初学者,仔细看看吧:. 1、如何比较字符串,应该用”==”还是equals(). 总的来说,”==”是用来比较字符串的引用地址,而equals()才是比较字符串的值. 两个值相同的字符串用”==”比较结果有可能是false,而用equals()则一定为true.

十个最常见的Java字符串问题 - liushaobo

- - 博客园_首页
翻译自: Top 10 questions of Java Strings. 用”==”还是用equals(). 简单地说,”==”测试两个字符串的引用是否相同,equals()测试两个字符串的值是否相同. 除非你希望检查两个字符串是否是同一个对象,否则最好用equals(). 2.为什么对于安全性敏感的信息char[]要优于String.

Java实现字符串反转的8种9种方法

- - ITeye博客
注:对于第7种使用异或的方式来实现字符串的反转,如果不太看得明白的,可以参照另一篇博客:. * 二分递归地将后面的字符和前面的字符连接起来. * 取得当前字符并和之前的字符append起来. * 将字符从后往前的append起来. * 和StringBuffer()一样,都用了Java自实现的方法,使用位移来实现.

内存泄漏

- - CSDN博客系统运维推荐文章
程序申请了堆空间,但是“忘记”释放,导致该块区域在程序结束前无法被再次使用导致的. 泄漏时间长了,就会导致用户空间内存不足,严重的导致死机. 如果泄漏比较严重,很容易察觉;但是有些泄漏很缓慢,不容易察觉,但是软件会运行很长时间后,会慢慢导致严重问题,而且当发现症状的时候,基本上已经是比较晚的时候了,想要识别泄漏,还是可以实现的,本篇文章来聊聊内存操作的原理.