`

String类substring方法导致的Java内存泄漏问题 (转)

    博客分类:
  • java
 
阅读更多

 

此问题在项目中被发现,经查看JDK源码(JDK1.6),String类的public String substring(int beginIndex, int endIndex)的实现让我很意外。

想重现这个场景很容易,请看代码。

 

 

 

 

执行此代码结果:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

 

问题就出在Huge类的 getSubString 方法,它调用了String类的substring方法。

来让我们看看 substring 类的实现吧,JDK源码如下:

 

    public String substring(int beginIndex, int endIndex) {
	if (beginIndex < 0) {
	    throw new StringIndexOutOfBoundsException(beginIndex);
	}
	if (endIndex > count) {
	    throw new StringIndexOutOfBoundsException(endIndex);
	}
	if (beginIndex > endIndex) {
	    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
	}
	return ((beginIndex == 0) && (endIndex == count)) ? this :
	    new String(offset + beginIndex, endIndex - beginIndex, value);
    }
 

 

 

再让我们接下来看看 new String(offset + beginIndex, endIndex - beginIndex, value); 的实现:

 

    // Package private constructor which shares value array for speed.
    String(int offset, int count, char value[]) {
	this.value = value;
	this.offset = offset;
	this.count = count;
    }
  

char[] value 数组被共享了。

 

在我们的main函数里的循环中,每循环一次后,我们希望Huge对象被回收,且释放它占有的内存。

但实际上 private String str = new String(new char[100000]); 占有的内存并不会被释放。

因为 我们通过 Huge 类的 getSubString 方法得到的 String 对象还存在(存在于handler的列表中),

它虽然是 length 只有 4 的对象,却享有着 char[100000] 的空间。

 

解决方案:

可以修改Huge 类的 getSubString 方法如下:

 

    public String getSubString(int begin, int end) {
        return new String(str.substring(begin, end));
    }
 

 

只要再套一个String的构造方法即可。

 

至于为什么,看看JDK源码,一看便知了。这里就不贴出来了。

分享到:
评论

相关推荐

    实现一个按字节来截取字符串的方法,功能类似于string类的substring方法,

    实现一个按字节来截取字符串的方法,功能类似于string类的substring方法,String类是按字符截取 的,例如"中国abc".substring(1,3),将返回“国a”。这里 要求按字节截取,一个英文字符当一个字节,一个中文字符当两...

    Java中由substring方法引发的内存泄漏详解

    主要介绍了Java中由substring方法引发的内存泄漏详解,涉及substring方法引发的内存泄漏简介,substring的作用和实现原理等相关内容,具有一定借鉴价值,需要的朋友可以参考下

    浅谈Java的String中的subString()方法

    下面小编就为大家带来一篇浅谈Java的String中的subString()方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Arduino项目开发 Strings_StringSubstring_StringSubstring.pdf

    Arduino项目开发 Strings_StringSubstring_StringSubstring.pdf 学习资料 复习资料 教学资源

    C#中String类的几个方法(IndexOf、LastIndexOf、Substring)

    C#中String类的几个方法(IndexOf、LastIndexOf、Substring)

    java 如何使用substring()方法截取子串

    java 如何使用substring()方法截取子串 java 如何使用substring()方法截取子串

    StringAPI.java

    Java String 类型 API 测试代码 1.String和char[]之间的转换 toCharArray(); 2.String和byte[]之间的转换 getBytes() Arrays工具类 : Arrays.toString(names) String类 String replace(char oldChar, ...

    String 截取字符串方法subString()

    String可以使用substring方法进行截取字符串有两种,参数可输入一个或者两个: 单参数:public ...String 类有一个方便的方法,叫做 substring​ ,正如其名称所示 , substring()​ 返回指定索引之间的 String 部分。

    3种js实现string的substring方法

    主要介绍了3种javascript实现string的substring方法,需要的朋友可以参考下

    java继承和接口,常用类

    根据“实验4说明”文件夹中给出的源程序MainTwo.java,StuList.java(其中的类实现了接口MyList),Student.java(其中的类Student是抽象类,其中,print( )方法是抽象方法)。 第二部分 编写一个类,该类的功能是...

    string类的常用方法.pdf

    string类是Java中的一种数据类型,用于表示文本字符串。它是不可变的,也就是说一旦创建了一个字符串对象,它的值就不能被修改。字符串类提供了许多方法来操作字符串,包括拼接、比较、截取和搜索等。 可以使用字符...

    自己实现string的substring方法 人民币小写转大写,数字反转,正则优化

    一、自己实现string的substring方法 方法一:用charAt取出截取部分 代码如下: String.prototype.mysubstring=function(beginIndex,endIndex){ var str=this, newArr=[]; if(!endIndex){ endIndex=str.length; } for...

    Java如何获取系统cpu、内存、硬盘信息

     前段时间摸索在Java中怎么获取系统信息包括cpu、内存、硬盘信息等,刚开始使用Java自带的包进行获取,但这样获取的内存信息不够准确并且容易出现找不到相应包等错误,所以后面使用sigar插件进行获取。下面列举出...

    javascript中String类的subString()方法和slice()方法

    在该书2.8.4节中讲到String类中的subString()方法和slice()方法,其用法和返回结果都基本相同,如下示例: 代码如下: var strObj = new String(“hello world”); alert&#40;strObj.slice(3&#41;); // 输出结果:”...

    Java截取(提取)子字符串(substring()).pdf

    在 String 中提供了两个截取字符串的方法,一个是从指定位置截取到字符串结尾,另一个是截取指定范围的内容。下面对这两种方法分别进行介绍。 1. substring(int beginIndex) 形式 此方式用于提取从索引位置开始至...

    完整版Java全套入门培训课件 Java基础 06-集合(共24页).pptx

    String类部分方法 char charAt(int index) int length() char[] toCharArray(); int indexOf(String str); boolean endsWith(String str); String[] split(String reg); String substring(int index); String(char[]...

    Java substring方法实现原理解析

    主要介绍了Java substring方法实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java常用方法大全

    一份很全面关于java的常用方法总结,开发时,我们记不了那么多方法,所以这个htm文档很适合大家在开中应用 字符串 1、获取字符串的长度 length() 2 、判断字符串的前缀或后缀与已知字符串是否相同 前缀 startsWith...

    Java substring原理及使用方法实例

    主要介绍了Java substring原理及使用方法实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    深入理解Swift中的Substring和String

    主要给大家深入的介绍了Swift中Substring和String的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。

Global site tag (gtag.js) - Google Analytics