String------subString()内存泄漏问题

7.Java中的subString()真的会引起内存泄露么?
答:这里首先有个问题,什么是内存泄露,那就向讲一讲内存溢出和内存泄漏的含义,所谓的内存溢出呢,就上内存不够用了,比如在一个无限的循环里不断的创建一个大的对象,使得沾满内存溢出,这就是所谓的内存溢出;而内存泄漏呢,就上指为一个对象分配好内存之后,在对象已经不再使用时未及时的释放,倒是一直占据内存单元,使实际可用内存减少,就好像内存泄漏了一样。内存泄漏问题其实就是在JDK1.6中,例如有一个字符串a,然后字符串b是字符串a的一个子字符串,就上使用substring()截取,这样的话a和b用的value是同一个引用,如果我们把a的引用为空,本意是释放a所占用的空间,但是这个时候,垃圾回收机制是没办法回收这个value的,因为这个还在被字符串b所引用,所以就会一直占着堆内存,就会导致内存泄漏。

解是这么解的,但是要注意这是jdk1.6之前的会产生的,在jdk1.8上不会产生这个问题,原因在与源码的改变。
原先subString源码:


   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);
	}


// 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;
    }


JDK1.8时,subString()源码,已经不在引用原来的char[]数组,而是建立了新的数组。

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

 public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }

    public static char[] copyOfRange(char[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        char[] copy = new char[newLength];
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
        return copy;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值