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

猜你喜欢

转载自blog.csdn.net/cz_chen_zhuo/article/details/117019549