2017-01-21 1 views
0

아래 코드 조각에서 Strings이 Java에서 변경 불가능하므로 수정 된 새 문자열을 저장하기 위해 새 개체 String이 생성됩니다. 그러나 어느 것이 새로운 객체를 생성 할 것인지, 그리고 어느 객체가 가비지 콜렉션을 위해 표시 될 것인지 확실하지 않습니다.새 개체를 만들고 가비지 수집을 위해 이전 개체를 선택하십시오.

String s1 = "It"; 
String s2 = "was"; 
String s3 = s1+" "+s2; 
s2+=" roses"; 
s3 = s3+s2+" roses all the way"; 
System.out.println(s3); 

답변

0

코드 스 니펫의 범위에 따라 다릅니다.

모든 코드가 하나의 메소드 안에 있으면 실행 후 모든 코드가 쓰레기로 처리됩니다.

가비지 수집기는 개체에 대한 참조 수에 따라 작동합니다.

예를 들어, 메서드 내에서 새로운 참조 String s1을 선언하고 무언가에 할당합니다. 그런 다음 메서드가 실행되고 완료되면 더 이상 참조가 없습니다. 그래서, 쓰레기로 가라.

+0

오해의 소지가 있습니다. 1. * 가비지 콜렉션 *을 구현할 수있는 참조 카운트 *가 있지만, Java에 사용되는 것으로 들어 본 적이 없습니다 (아마도 사이클을 처리 할 수 ​​없을 것입니다.). 사용 된 가비지 컬렉터는 정확한 참조 횟수에 대해 알지 못합니다. 그들은 단지 참조되거나 그렇지 않은 것을 안다. 2. 메소드가 완료되면, "It"은 모든 참조를 잃어 버렸지 만, 리터럴 풀의 멤버는 아무도 신경 쓰지 않습니다. 3. 메소드가 종료 될 때 명시적인 GC 조치가 취해지지 않습니다 (반대를 주장하지 않았지만 이해할 수 있습니다). – maaartinus

+0

@maaartinus - 네 말이 맞을 것 같아. 그러나 "참조 횟수"또는 "참조 횟수"- 차이점은 무엇입니까? count == 0은 unreferenced를 의미합니다 :-). 나는 진짜로 "누가 신경 쓰냐?"라는 이유로 문자열에 특히주의를 기울이지 않았다. :-). 방금 전에 GC가 객체 (문자열이 아닌)를 먼저 파괴하도록 null을 참조로 설정해야하는 경우가있었습니다. ... 오랜 시간 ... – Vadim

0

이것은 간단한 기본 설명이며 실제 동작은 사용되는 컴파일러와 JVM에 따라 다를 수 있습니다. 또한이 주제에 깊이 들어가고 더 자세한 설명을 제공 할 수있는 많은 기사가 있습니다.

이러한 리터럴은 JVM의 문자열 풀에 저장되며 GC'ed되지 않습니다. (즉, 그들은 JVM의 기간 동안 메모리에 존재합니다.

"It", "was", " ", " roses", " roses all the way" 

을 그리고, 지금까지의 문자열 참조에 관한 한, 그것은 변수의 범위에 따라 달라집니다. 나는이 대답을 지역 메소드 레벨을 가정합니다 :

String s1 = "It"; // a reference will be created on the stack 

String s2 = "was"; // a reference will be created on the stack 

String s3 = s1+" "+s2; // a reference will be created on the stack for s3, and then two temp objects will be created in memory, one for s1+" ", one for concatenating the result with +s2. (this operation can vary greatly based on how compiler optimizes), the first one will become eligible for GC immediately. 

s2+=" roses"; // same as above. 

s3 = s3+s2+" roses all the way"; // same as above but the object s3 was pointing to will become eligible for GC immediately. 

System.out.println(s3); // no memory allocation. 

방법은 S2, S1, 종료, 및 S3 참조가 스택에서 삭제되며 나머지 객체가,이 도움이

희망 GC 대상이 될 이것은 매우 기억을 지적했다. 기본 설명, 나는이 주제에 대해 읽는 것이 좋습니다. t는 실제로 컴파일러가 최적화를 결정하는 방법에 따라 크게 달라질 수 있습니다. 예를 들어, 컴파일러는 이러한 임시 참조를 모두 볼 수 있으며 연결을 필요 없으며 삭제할 수 있습니다.

참고 : 문자열을 연결하기 위해 연결하기 때문에 StringBuffer 또는 StringBuilder와 같은 Mutable 대안을 고려할 수 있습니다. 최적화.

관련 문제