두 번째 행의 출력 결과는 상당히 놀랍다. 이는 tmp를 사용하는 것이 매번 obj.value를 사용하는 것과 동일하지 않다는 것을 보여준다. 실제로 tmp는 초기화 시 obj.value로 표현된 필드의 별칭 역할을 한다. 그림 13-6은 Main 메서드의 끝에 도달했을 때 변수의 객체가 어떻게 보이는지를 나타내고 있다.
▲ 그림 13-6 예제 13-4가 마지막까지 수행된 이후 obj가 다른 인스턴스를 참조하더라도 tmp 변수는 여전히 첫 번째 인스턴스의 필드를 참조하고 있음
이러한 결과로 추론해 보자면, 첫 번째 인스턴스는 tmp 메서드가 없어지지 않는 한 가비지로 수집되지 않을 것이다. 또한, 배열을 참조하는 참조 지역 변수를 생성하게 되면, 배열 요소 또한 가비지로 수집되지 않을 것이다.
Note ≡
객체 내의 필드나 배열 요소를 참조하는 참조 지역 변수는 가비지 수집기의 동작을 더욱 복잡하게 만든다. 가비지 수집기는 특정 객체가 다른 변수에 의해서 참조되고 있는지를 확인하여 객체의 수명을 판단하는데, 일반적인 객체 참조는 해당 객체를 직접 참조하기 때문에 비교적 간단하게 처리할 수 있다. 하지만 특정 객체 내의 필드를 참조하는 지역 변수는 가비지 수집기가 관리하는 데이터 구조체를 가리키는 내부 포인터(interior pointer)를 가지고 있다. 동시에 참조 지역 변수가 너무 많아지면 비용이 증가할 수밖에 없지만, 다행히 참조 지역 변수는 항상 스택에만 존재하기 때문에 성능 문제를 야기할 가능성은 거의 없다.