2017-11-09 3 views
0

질문이있어서 혼란 스럽습니다.은 자바 패스 바이 값입니까? 가비지 콜렉션 관련

가비지 콜렉션을 사용할 수있는 8 번째 코드를 실행 한 후?

public class X 
{ 
    public static void main(String [] args) 
    { 
     X x = new X(); 
     X x2 = m1(x);   /* Line 6 */ 
     X x4 = new X(); 
     x2 = x4;    /* Line 8 */ 
     doComplexStuff(); 
    } 
    static X m1(X mx) 
    { 
     mx = new X(); 
     return mx; 
    } 
} 

.x를
는 B .x를 및 X2
C는 .x를 4 배속 D는 .x4

은 내 초기 생각은 X2는 가비지
을 수집 하였다 왜냐하면 x2 = x4 일 때 8 행에서 해설되고 java는 값으로 전달되기 때문에 X2 = m1 (x)는 x에 영향을주지 않습니다.

나는 똑같은 질문 (그러나 다른 선택)을 여기에서 발견했다. https://www.indiabix.com/java-programming/garbage-collections/discussion-202 그리고 x는 또한 가비지 수집되어야한다고 말하면서, 내 생각과 모순된다. 지금 나는 어느 선택에 대해 혼란스러워한다. 질문은 정확합니다, 미리 감사드립니다.

+1

귀하의 이해가 정확합니다. GC에 적합한 유일한 객체는'x2'에 의해 참조 된 객체입니다. – shmosel

+2

[Java가 "pass-by-reference"또는 "pass-by-value"입니까?] (https://stackoverflow.com/questions/40480/is-java-pass-by-reference-orpass) -by-value) –

+0

* 모두 *. 로컬 변수가 참조하는 것은 가비지 수집을 방지하기에 충분하지 않습니다. 'doComplexStuff()'를 실행하는 동안,이 객체들 중 아무 것도 사용되지 않으며 이후에 사용되지 않을 것이다. JVM이 실제로 JVM을 수집 할 수 있는지 여부는 기술적 인 세부 사항에 달려 있습니다. JIT/옵티마이 저가 이미 코드를 처리했는지 여부에 관계없이 이러한 기술적 세부 사항은 * 원칙적으로 * 변경되지 않습니다. 이러한 모든 오브젝트는 가비지 수집이 허용됩니다. – Holger

답변

0

네, 맞습니다.

Java는 "값으로 전달"이며 mx, mx = new X(); 만 가비지 수집됩니다.

x은 가비지 수집되지 않습니다. 예를 들어;

public class X 
{ 
    public static void main(String [] args) 
    { 
     X x = new X(); 
     X x2 = m1(x); 
     X x4 = new X(); 
     x2 = x4; 
     doComplexStuff(); 
     System.out.print(x); // no problem; line 10 
    } 
    static X m1(X mx) 
    { 
     mx = new X(); 
     return mx; 
    } 
} 

x가 가비지 수집되는 경우 10 번 라인 오류입니다. 사실, 그렇지 않습니다. 그래서 x은 쓰레기 수거가되지 않습니다.

+0

안녕하세요 fxleyu, 당신의 답변을 주셔서 감사합니다 x2 쓰레기도 수집입니까? 왜 안되지? 나는 x2 = x4 라인 8에서 x2의 원래 값을 derefenced하고 가비지 콜렉션으로 간다고 생각했다. – VinceFIT

+0

네,'x2', 당신이 참조하는'mx','mx = new X();'; – fxleyu

1

나는 이것이 특히 문안이 잘 안된 질문이라고 생각하지 않습니다.

우선 변수는 가비지 수집 대상이 될 수 없습니다. 개체는 할 수 있습니다. 따라서 x2이 GC에 적합하다는 것은 아무 것도 의미가 없습니다. 그 이유는 메서드가 반환 된 이후 mx도 적합하다고 말할 수 있기 때문입니다. 이렇게하면 실제로있는 것보다 많은 메모리가있는 것처럼 보입니다.

이것은

라인 (12)에서 생성 된 객체는 GC에 적합한 지 더 정확하다.

또한 5 행에서 생성 된 개체는 적합하지 않으며, x은 여전히이 개체를 참조합니다. x의 값을 인쇄 해보십시오. null이 아님을 알 수 있습니다.

+0

@ piet.t 편집 됨. – Sweeper

+0

이것은 무의미한 테스트입니다. 'x'를 인쇄 할 명령문을 삽입하면'x'의 가비지 콜렉션을 막는 삽입 문입니다. print 문이 존재하지 않을 때'x'에 의해 참조 된 객체가 가비지 컬렉터가 아니라는 것을 증명하지 않습니다. 특히 가비지 콜렉터는 'null'에 대한 참조를 설정하지 않습니다. * unused *로 판명 된 무언가를 'null'로 설정하는 것은 무의미합니다. – Holger

2

많은 사람들이 x2에서 참조하는 응답 객체가 가비지 수집됩니다. 다음은 GC를 직접 확인하고이 코드가 자바의 동작을 보여주기위한 예제 코드입니다.

Java는 객체를 참조로 조작하지만 객체 참조를 값으로 전달합니다.

public class GCInJava 
{ 
    int i=0; 
    String name="default"; 
    @Override 
    protected void finalize() throws Throwable { 
     super.finalize(); 
     System.out.println("[GCing object referenced by: "+this.name+"]"); 
    } 
    public static void main(String [] args) 
    { 
     GCInJava x = new GCInJava(); 
     x.name="x"; 
     System.out.println("x before calling m1(): "+x); 
     System.out.println("x.i before calling m1(): "+x.i); 
     GCInJava x2 = m1(x);  
     System.out.println("x.i after calling m1(): "+x.i); 
     System.out.println("x after calling m1(): "+x); 
     System.out.println("x2.i: "+x2.i); 
     GCInJava x4 = new GCInJava(); 
     x4.name="x4"; 
     x2 = x4;    
     System.gc(); 
     doComplexStuff(); 
    } 
    static GCInJava m1(GCInJava mx) 
    { 
     System.out.println("mx before new object: "+mx); 
     mx = new GCInJava(); 
     mx.i=10; 
     mx.name="mx/x2"; 
     System.out.println("mx after new object: "+mx); 
     return mx; 
    } 
} 

참고 :System.gc() 항상 가비지 콜렉션이 JVM에 의해 트리거하지 않을 수 있습니다; 코드를 몇 번 실행 해보십시오.

샘플 출력 (해쉬 코드가 인쇄 된 통지)

X M1()를 호출하기 전에 다음 새로운 객체 전에 0
MX :
XI M1()를 호출하기 전에 [email protected] 테스트 .GCInJava 새로운 객체 후 64c3c749
MX @는 : [email protected]
x2.i : 10

012,351,641 M1()를 호출 한 후 0
X : M1()를 호출 한 후
XI을 [email protected]

[GCing 객체 참조 : mx/x2]