itsource

String에 "를 추가하면 메모리가 절약되는 이유는 무엇입니까?

mycopycode 2022. 7. 21. 23:39
반응형

String에 "를 추가하면 메모리가 절약되는 이유는 무엇입니까?

, 를 들어 '를 사용했는데요.String data 사용하고

this.smallpart = data.substring(12,18);

( 비주얼라이저를 디버깅을 몇 동안 필드('메모리 비주얼라이저가 되었습니다.smallpart 데이터를 기억하다data

코드를 다음과 같이 변경했을 때:

this.smallpart = data.substring(12,18)+""; 

..문제가 해결되었다!이제 내 앱은 메모리를 거의 사용하지 않습니다!

어떻게 그것이 가능한가요?누가 이걸 설명할 수 있나요?제 생각엔 작은 부분은 계속 데이터를 참조하는데, 왜일까요?

업데이트: 그러면 큰 문자열을 지우려면 어떻게 해야 합니까?data = new String(data.substring(0,100))이 작업을 수행할 수 있습니까?

다음을 수행합니다.

data.substring(x, y) + ""

는 새로운 (더 작은) String 객체를 생성하여 서브스트링()에 의해 작성된 String에 대한 참조를 폐기함으로써 가비지 수집을 newable로 합니다.

깨달아야 할 중요한 것은substring()기존 String(또는 원래 String의 기초가 되는 문자 배열)에 대한 창을 보여줍니다.따라서 원래 String과 동일한 메모리를 사용합니다.이것은 경우에 따라서는 편리할 수 있지만, 서브스트링을 취득해 원래의 String을 폐기하는 경우는 문제가 있습니다(알고 있듯이).

자세한 내용은 JDK String 소스의 substring() 메서드를 참조하십시오.

편집: 보충 질문에 답하기 위해 서브스트링에서 새로운 String을 작성하면 원래 String에 대한 참조를 모두 삭제하면 메모리 소비량이 줄어듭니다.

참고 (2013년 1월)위의 동작은 Java 7u6에서 변경되었습니다.Flyweight 패턴은 더 이상 사용되지 않습니다.substring()예상대로 동작합니다.

substring(int, int)뭇매를 맞다

new String(offset + beginIndex, endIndex - beginIndex, value);

서 ''는value 원조입니다.char[]그러면 새로운 String을 얻을 수 있지만 기본은 동일합니다.char[].

경우, ★★★★★★★★★★★★★★★★.data.substring() + "", 새로운 기반이 되는 새로운 String을 얻을 수 있습니다.char[].

는 '사용 사례', '사용 사례', '사용 사례', '사용 사례', '사용 사례', '사용 사례', ' 사례'만.String(String)★★★★★★★★★★★★★★★★★★:

String tiny = new String(huge.substring(12,18));

「 」를 사용하는 substring새 문자열은 실제로 생성되지 않습니다.여전히 오프셋 및 크기 제약이 있는 원래 문자열을 참조합니다.

원래 수 새 .new String 것 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

제 생각엔 작은 부분은 계속 데이터를 참조하는데, 왜일까요?

자바 문자, 해시 코드(hash Code) 문자oper음음음음ationsationsationsations 등의 문자열 .substring()원본의 문자 배열을 공유하고 오프셋 및/또는 길이 필드가 서로 다른 새 문자열 개체를 만듭니다.이것은 String의 char 배열이 작성된 후에는 변경되지 않기 때문에 작동합니다.

이렇게 하면 중복되는 부분을 복제하지 않고 많은 서브스트링이 동일한 기본 문자열을 참조할 때 메모리를 절약할 수 있습니다.이미 알고 있듯이 상황에 따라 더 이상 필요하지 않은 데이터가 수집되지 않도록 할 수 있습니다.

하는 '은 '올바른' 방법입니다.new String(String)스트럭럭 、 ★

this.smallpart = new String(data.substring(12,18));

BTW, 가장 좋은 해결책은 처음부터 매우 큰 문자열이 있는 것을 피하고 작은 청크(aa 몇 KB)로 입력을 처리하는 것입니다.

Java 문자열은 변경할 수 없는 개체이며, 문자열이 생성되면 가비지 콜렉터에 의해 지워질 때까지 메모리에 남아 있습니다(이 클리닝은 당연하게 받아들일 수 없습니다).

서브스트링 메서드를 호출하면 Java는 완전히 새로운 문자열을 작성하지 않고 원래 문자열 안에 문자 범위만 저장합니다.

따라서 다음 코드를 사용하여 새 문자열을 작성했을 때:

this.smallpart = data.substring(12, 18) + ""; 

결과를 빈 문자열과 연결하면 실제로 새 문자열이 생성됩니다.그래서 그런 거야.

1997년 jwz에 의해 문서화된 바와 같이:

큰 문자열이 있는 경우 그 서브스트링()을 꺼내서 서브스트링을 잡고 긴 문자열이 가비지(즉, 큰 문자열의 기본 바이트가 사라지지 않습니다).

요약하자면, 소수의 큰 문자열로 많은 서브스트링을 작성하면

   String subtring = string.substring(5,23)

큰 끈을 저장하는 데만 공간을 사용하지만, 큰 끈의 손실에서 작은 끈을 몇 개만 추출할 경우,

   String substring = new String(string.substring(5,23));

대용량 문자열은 더 이상 필요하지 않을 때 재확보할 수 있으므로 메모리 사용량을 줄일 수 있습니다.

것은 '아예'new String는 원래 문자열에 대한 참조가 아니라 실제로 새 문자열을 얻을 수 있음을 알려주는 데 도움이 됩니다.

첫째, 호출하면 기본 배열의 중요한 부분을 복사하는 대신 오프셋과 길이를 사용하여 원본에 새 창이 생성됩니다.

더 자세히 보면substring메서드는 문자열 생성자 호출에 주목합니다.String(int, int, char[])통째로 넘기고char[]스트링을 나타냅니다., 서브스트링이 원래 문자열과 같은 양의 메모리를 차지합니다.

왜 래, 데는 거죠?+ ""메모리가 없는 경우보다 더 적은 메모리가 필요합니까?

을다하 +strings 통해 됩니다.StringBuilder.append 이 방법의 .AbstractStringBuilder ' 하다'는 것을 거예요.arraycopy 됩니다.substring를 참조해 주세요.

다른 해결 방법은?

this.smallpart = new String(data.substring(12,18));
this.smallpart = data.substring(12,18).intern();

문자열에 "를 추가하면 메모리가 절약될 수 있습니다.

책 한 권이 들어 있는 큰 끈이 있다고 칩시다. 백만 글자에요.

그리고 책의 각 장을 밑줄로 한 20개의 줄을 만듭니다.

그러면 모든 단락을 포함하는 1000개의 문자열을 만듭니다.

그리고 모든 문장을 포함하는 10,000개의 문자열을 만듭니다.

그리고 모든 단어를 포함하는 100,000개의 문자열을 만듭니다.

저는 아직 100만 글자밖에 안 써요.각 장, 단락, 문장, 단어에 "를 추가하면 500,000자를 사용할 수 있습니다.

물론 책 전체에서 한 단어만 뽑아낸다면 완전히 다를 수 있고, 책 전체가 쓰레기 수집품일 수도 있지만, 그 한 단어가 그 단어에 대한 언급을 가지고 있기 때문은 아닙니다.

또한 100만 개의 문자열이 있고 양 끝에 탭과 공백을 제거하여 하위 문자열을 생성하기 위해 10개의 호출을 하는 경우에도 다릅니다.Java가 동작하거나 동작하는 방식은 매번 백만 개의 문자를 복사하는 것을 방지합니다.타협이 있고, 타협이 무엇인지 아는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/2147783/why-does-appending-to-a-string-save-memory

반응형