기억이 나지 않음 : 평신도의 용어로는 메모리가 충분하지 않다는 것을 의미합니다. 예를 들어, 무한 루프에서 지속적으로 큰 객체를 생성하면 곧 메모리 오버플로가 발생합니다.
메모리의 누출 : 객체가 더 이상 사용되지 않을 때 메모리를 물체에 할당 한 후 메모리를 적시에 해제하는 것을 의미합니다.
서브 스트링 방법으로 인한 메모리 누출
서브 스트링 (int beginindex, int endndex)은 문자열 클래스의 메소드이지만이 방법은 JDK6 및 JDK7에서 완전히 다르게 구현됩니다 (둘 다 동일한 효과를 달성하지만). JDK1.6에서 부적절한 서브 스트링을 사용하는 것이 심각한 메모리 누출 문제로 이어질 수 있기 때문에 구현 세부 정보를 이해하면 더 나은 사용에 도움이 될 수 있습니다.
1. 서브 스트링의 역할
기판 (int beginindex, int endindex) 메소드는 부모 문자열의 시작 부분에서 시작하여 endindex-1에서 엔드 스트링을 반환합니다. 상위 문자열의 첨자는 0에서 시작되며 서브 스트링에는 endIndex가 아닌 stegtring이 포함되어 있습니다.
문자열 x = "abcdef"; x = str.substring (1,3); System.out.println (x);
위 프로그램의 출력은 "BC"입니다.
2. 구현 원리
문자열 클래스는 불변입니다. 위의 두 번째 문장에서 x가 재 할당되면 새 문자열 객체를 가리 킵니다. 그러나 정확한 설명은 없거나 힙에서 발생하는 실제 상황을 나타냅니다. 서브 스트링이라고 할 때 실제로 발생하는 것은 둘 사이의 차이입니다.
JDK6의 하위 문자열 구현
문자열 객체는 숯 배열로 저장됩니다. 문자열 클래스에는 3 개의 필드가 있습니다 : char [] value, int offset 및 int count는 각각 실제 문자 배열, 배열의 시작 위치 및 문자열의 문자 수를 저장하는 데 사용됩니다. 이 3 가지 변수는 문자열을 결정할 수 있습니다. 하위 문자열 메소드가 호출되면 새 문자열이 생성되지만 위의 숯 배열 값은 여전히 원래 상위 배열의 값을 사용합니다. 부모와 자식 배열의 유일한 차이점은 카운트와 오프셋 값이 다르다는 것입니다.
JDK6의 하위 문자열 구현의 소스 코드를 살펴보십시오.
public string substring (int beginindex, int endindex) {if (beginIndex <0) {새 stringIndexOutOfBoundSexception (beginIndex); } if (endIndex> count) {새 stringIndExOutOfBoundSexception (endIndex); } if (beginIndex> endIndex) {새 stringIndexOutOfBoundSexception (endIndex -beginIndex); } return ((beginindex == 0) && (endIndex == count))? 이것 : 새 문자열 (Offset + beginIndex, endIndex -beginIndex, value); // 상위 문자열과 동일한 숯 배열 값을 사용하는 데 사용됩니다.} 문자열 (int offset, int count, char value []) {this.value = value; this.offset = 오프셋; this.count = count; }String str = "abcdefghijklmnopqrst"; String sub = str.substring (1, 3); str = null;
이 간단한 프로그램에는 두 개의 문자열 변수 str과 sub가 있습니다. 하위 문자열은 부모 문자열 str에 의해 얻어집니다. 위의 프로그램이 JDK1.6에서 실행되면 배열의 메모리 공간 할당이 힙에서 수행된다는 것을 알고 있습니다. 서브와 STR의 내부 숯 배열 값은 동일합니다. STR과 SUB의 유일한 차이점은 배열의 시작 인덱스와 문자 길이 수의 차이입니다. 세 번째 문장에서, 우리는 STR에 의해 점유 된 공간을 해방시키기위한 STR 참조를 비워 둡니다. 그러나 현재 GC는이 큰 char 배열이 서브 문자열 내부에서 참조되기 때문에이 큰 숯 배열을 재활용 할 수는 없지만, 하위는이 큰 배열의 작은 부분만을 가로 채겠습니다. STR이 매우 큰 문자열 인 경우이 폐기물은 매우 명백하며 성능 문제를 가져올 수도 있습니다. 이 문제를 해결할 수 있습니다.
문자열 스 플라이 싱 기술을 사용하여 새 문자열이 생성됩니다. 이 새 문자열은 새로운 내부 Char 배열을 사용하여 실제로 필요한 문자를 저장하므로 상위 배열의 숯 배열은 다른 소스에서 참조되지 않습니다. STR = NULL을 보자, 다음에 GC가 재활용 될 때 STR이 차지하는 전체 공간이 재활용됩니다. 그러나 이와 같은 글쓰기는 분명히 잘 보이지 않으므로 JDK7에서는 서브 스트링이 다시 구현됩니다.
JDK7의 하위 문자열 구현
JDK7에서 하위 문자열 구현이 향상되어 실제로 가로 채워진 하위 문자열이 하위 문자를 보유 할 수 있도록 힙에 새로운 숯 배열을 만듭니다.
JDK7에서 문자열 클래스의 하위 문자열 메소드의 구현 소스 코드를 확인하십시오.
public string substring (int beginindex, int endindex) {if (beginIndex <0) {새 stringIndexOutOfBoundSexception (beginIndex); } if (endIndex> value.length) {새 stringIndexOutOfBoundSexception (endIndex); } int sublen = endIndex -beginIndex; if (sublen <0) {새 stringIndexOutOfBoundSexception (sublen); } return ((beginIndex == 0) && (endIndex == value.length))? 이것 : 새 문자열 (value, beginindex, sublen); } public String (char value [], int offset, int count) {if (offset <0) {throw new stringIndExoutOfBoundSexception (오프셋); } if (count <0) {새 stringIndExOutOfBoundSexception (count); } // 참고 : 오프셋 또는 카운트가 -1 >>> 근처에있을 수 있습니다. if (offset> value.length -count) {새 stringIndexOutOfBoundSexception (오프셋 + count); } this.value = arrays.copyofRange (값, 오프셋, 오프셋+count); }배열 클래스의 CopyOfRange 메소드 :
public static char [] copyofrange (char [] original, int from, int to) {int newlength = to -from; if (newlength <0) 새로운 불법 불법 행위 ( + ">" + to)를 던지십시오. char [] copy = new char [newlength]; // 새 Char 배열 시스템을 만드는 것입니다. ArrayCopy (원본, From, From, Copy, 0, Math.min (Original.length- from, Newlength)); 반환 사본; }서브 스트링이 문자를 서브 스트링에 저장하기 위해 새로운 숯 배열이 생성된다는 것을 알 수 있습니다. 이런 식으로 자식 문자열과 부모 문자열 사이에는 필요한 연결이 없습니다. 부모 문자열의 참조가 유효하지 않은 경우 GC는 부모 문자열이 차지하는 메모리 공간을 적시에 재활용합니다.
요약
위는 Java의 서브 스트링 방법으로 인한 메모리 누출에 대한 전체 설명입니다. 모든 사람에게 도움이되기를 바랍니다. 관심있는 친구는이 사이트의 다른 관련 주제를 계속 참조 할 수 있습니다. 단점이 있으면 메시지를 남겨 두십시오. 이 사이트를 지원해 주신 친구들에게 감사드립니다!