10분 동안 자바의 약한 인용을 이해해 드리겠습니다.

3845 단어 java약인용
앞말
본고는 What, Why, How 등 세 가지 측면에서 자바에서의 약한 인용을 탐색하여 자바에서의 약한 인용의 정의, 기본적인 사용 장면과 사용 방법을 이해하는 데 도움을 주려고 한다.
1. What―약인용이 무엇입니까?
Java의 약인용은 구체적으로 java.lang.ref.WeakReference<T> 클래스를 가리키며, 먼저 공식 문서에 대한 설명을 살펴보겠습니다.
약한 인용 대상의 존재는 가리키는 대상이 쓰레기 수거기에 회수되는 것을 막지 못한다.약한 인용의 가장 흔히 볼 수 있는 용도는 규범화 맵핑(canonicalizing mappings, 예를 들어 해시표)을 실현하는 것이다.
만약에 쓰레기 수집기가 특정한 시간에 하나의 대상이 약한 인용(weakly reachable) (현재 그것을 가리키는 것은 모두 약한 인용) 이라고 결정한다면, 쓰레기 수집기는 이 대상을 가리키는 모든 약한 인용을 제거하고, 이 약한 인용을 종결 가능한 (finalizable) 으로 표시합니다. 그러면 나중에 회수됩니다.이와 함께 또는 나중에 스팸 컬렉터가 지워진 약한 참조를 약한 참조 객체를 만들 때 지정한 참조 대기열(Reference Queue)에 넣습니다.
실제로 자바에는 네 가지 인용이 존재하는데 강에서 약으로 이어지는 것은 강인용, 소프트인용, 약인용, 허인용이다.
다음은 약한 인용을 제외한 세 가지 인용을 간단히 소개합니다.
1. 강한 인용(Strong Reference): 일반적으로 우리가 new를 통해 새로운 대상을 만들 때 되돌아오는 인용은 강한 인용입니다. 만약에 하나의 대상이 일련의 강한 인용을 통해 도착할 수 있다면, 강한 인용(strongly reachable)은 회수되지 않습니다.
2. 소프트 참조(Soft Reference): 소프트 참조와 소프트 참조의 차이점은 한 객체가 약한 참조인 경우 현재 메모리가 충분하든 충분하지 않든 회수되고, 소프트 참조인 객체는 메모리가 충분하지 않을 때 회수되기 때문에 소프트 참조가 약한 참조보다 낫다는 점입니다.
3. 거짓 참조(Phantom Reference): 거짓 참조는 Java에서 가장 약한 참조입니다. 그러면 어느 정도 약합니까?이것은 우리가 인용된 대상을 얻기 어려울 정도로 취약하다. 인용이 존재하는 유일한 역할은 가리키는 대상이 회수되면 인용 대기열에 삽입되어 인용된 대상이 회수되었다는 것을 기록하는 것이다.
2. Why―왜 약한 인용을 사용합니까?
아래의 장면을 고려한다. 현재 하나Product류는 하나의 제품을 대표하고 이 종류는 확장할 수 없는 것으로 설계되었다. 이때 우리는 모든 제품에 번호를 추가하고자 한다.하나의 해결 방안은 사용HashMap<Product, Integer> 이다.그래서 문제가 생겼다. 만약에 우리가 메모리에 존재하는 대상(예를 들어 이 제품을 팔았다)이 더 이상 필요하지 않다면, 그것을 가리키는 인용이 Product 이라고 가정하면, 우리는 productAproductA 으로 값을 부여할 것이다. 그러나 이때 null 과거에 가리키는 productA 대상은 회수되지 않을 것이다. 왜냐하면 이것은 분명히 Product 인용되고 있기 때문이다.그래서 이런 상황에서 우리는 진정으로 하나의 HashMap 대상을 회수하고 싶다. 단지 그것의 강한 인용부치를 Product 로 하는 것만으로는 부족하고 해당하는 항목을 null 에서 제거해야 한다.분명히 HashMap에서 더 이상 필요하지 않은 항목을 제거하는 작업은 우리가 스스로 완성하고 싶지 않다. 우리는 쓰레기 수집기에게 HashMap 중의 HashMap 대상만 인용하고 있는 상황에서 상응하는 key 대상을 회수할 수 있다고 알려주고 싶다.분명히 앞의 약인용의 정의에 따라 약인용을 사용하면 우리가 이 목적을 달성하는 데 도움을 줄 수 있다.우리는 단지 Product 대상을 가리키는 약한 인용 대상을 Product 중의 Product 로 하면 된다.
3. How―약한 인용을 어떻게 사용합니까?
위에서 소개한 장면을 예로 들면 우리는 HashMap 대상을 가리키는 약한 인용 대상을 keyProduct로 사용한다. 이 약한 인용 대상을 이렇게 정의하기만 하면 된다.

Product productA = new Product(...);
WeakReference<Product> weakProductA = new WeakReference<>(productA);
현재 인용 대상HashMapkey 대상weakProductA을 가리킨다.그러면 우리는 어떻게 Product를 통해 그것이 가리키는 productA 대상weakProduct을 얻을 수 있습니까?
간단합니다. 아래 코드만 있으면 됩니다.

Product product = weakProductA.get();
실제로 이런 상황에 대해 자바 라이브러리는 우리에게 Product 클래스를 제공했다. 사용과 이 클래스의 키는 자연히 약한 인용 대상이기 때문에 우리가 원시 대상을 수동으로 포장할 필요가 없다.이렇게 되면 productAWeakHashMap 로 변할 때 (인용된 productA 메모리에 존재할 필요가 없음을 나타낸다) 이때 이 null 대상을 가리키는 것은 약한 인용 대상Product이 된다. 그러면 분명히 이때 해당하는 Product 대상이 약할 수 있기 때문에 약한 인용을 가리키는 것은 제거되고 이 weakProductA 대상은 회수된다.그것을 가리키는 약한 인용 대상은 인용 대기열에 들어갑니다.
4. 참조 대기열
다음은 인용 대열의 개념을 간단하게 소개합니다.실제로 Product 클래스에는 다음과 같은 두 가지 구조 함수가 있습니다.

// 
WeakReference(T referent) 
// 
WeakReference(T referent, ReferenceQueue<? super T> q)
우리는 두 번째 구조 방법에서 Product 유형의 매개 변수를 제공한 것을 볼 수 있다. 이 매개 변수를 제공함으로써 우리는 만들어진 약한 인용 대상을 하나의 인용 대기열에 등록했다. 이렇게 하면 쓰레기 수거기에 의해 제거될 때 이 인용 대기열에 보내서 제거된 약한 인용 대상을 통일적으로 관리할 수 있다.
5. 총결산
자, 이 글의 내용은 여기까지 끝났습니다. 개인의 수준이 제한되어 있기 때문에 서술에서 부정확하거나 명확하지 않은 부분이 존재하지 않을 수 없습니다. 여러분이 저희에 대한 지지에 감사드린다고 지적해 주시기 바랍니다.

좋은 웹페이지 즐겨찾기