자바 참조 종류 2

자바 참조 종류

강한 참조( Strong references )

HashMap<Integer, String> hashMap = new HashMap<>();

강한 참조가 단점으로 작용할 때 ( When Strong references are too Strong )

Widget이라는 클래스를 당신이 사용하는데 Widget 클래스에 새로운 기능을 상속을 통해 추가하려 하는데( Opened ) 어떤 이유에선지 그럴 수 없다고 해보자. (Widget이 final 클래스이라서거나 등등 이유는 많다.) 그렇다면 그 Widget 객체의 추가적인 정보가 생겼으면 그것들을 어떻게 추적할 것인가? (Widget의 자식을 만들어 필드로 저장하는 옳겠지만 Widget 클래스는 확장될 수 없어서 그럴 수 없다.) 예를 들어, Widget의 시리얼 넘버를 추적하고 싶은데 확장을 할 수 없어 추가 할 수 없다. HashMap을 써서 Widget 객체를 ket로, 시리얼 넘버를 value로 저장하는 방법이 있지 않을 까? HashMap을 다음과 같이 쓰면 문제가 해결되고 HashMap도 별 문제가 없어 보인다.

serialNumberMap.put(widget, widgetSerialNumber);

표면적으로는 매우 괜찮아 보이지만, Widget에 대한 강한 참조는 확실히 문제들을 일으킨다. 이 방식은 우리가 언제 특정한 Widget의 시리얼 넘버가 더 이상 필요 없을 때를 알아야 한다(정확히 100%로), 그래야 우리는 map으로부터 그 entry를 지울 수 있기 때문이다. 그렇지 않으면
[문제1]메모리 누수가 발생할 것이다(만약 우리가 map에서 지워야 할 Widget을 지우지 않을 경우).

[문제2]또 그 Widget 객체의 시리얼 넘버를 나도 모르게 누락할 위험도 있다.(계속 사용할 Widget 객체를 실수로 map에서 지울 경우)


=> 무슨 말이냐면,
[문제1] widget 이라는 Widget 객체가 있고 이것을 HashMap<Widget, Integer> 에 추가했다고 하면 더이상 widget이 필요 없어졌을 때 widget = null 로 처리했더라도 까먹고 HashMap에 추가한 Widget 객체를 제거하지 않았다면 강한 참조가 계속 존재하는 거라 GC는 widget을 garbage라 인식 못해 처리하지 못하고 결국 메모리 누수(memory leak) 가 발생한다는 뜻이다.

[문제2] 또 map에서 지우지 말아야 할 Widget 객체를 지웠다면 나중에 그 객체의 시리얼 넘버를 조회하고 싶어도 map에서 시리얼 넘버가 이미 삭제되어 조회할 수 없고 이렇게 누락 됐다는 것조차 모른다는 것을 말한다. (=> Widget 객체는 map 밖에서도 강한 참조를 하니깐 삭제는 안될 것이지만 시리얼 넘버는 map에만 있는 데이터이고 실수로 삭제했으면 구할 방법은 없다.)

약한 참조 ( Weak references )

참조 대기열 ( Reference queues )

소프트 참조 ( Soft references )

유령 참조 ( Phantom references )


출처: https://web.archive.org/web/20061130103858/http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
관련글 : https://d2.naver.com/helloworld/329631 (네이버 D2)