10분 동안 자바의 약한 인용을 이해해 드리겠습니다.
본고는 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
이라고 가정하면, 우리는 productA
에 productA
으로 값을 부여할 것이다. 그러나 이때 null
과거에 가리키는 productA
대상은 회수되지 않을 것이다. 왜냐하면 이것은 분명히 Product
인용되고 있기 때문이다.그래서 이런 상황에서 우리는 진정으로 하나의 HashMap
대상을 회수하고 싶다. 단지 그것의 강한 인용부치를 Product
로 하는 것만으로는 부족하고 해당하는 항목을 null
에서 제거해야 한다.분명히 HashMap
에서 더 이상 필요하지 않은 항목을 제거하는 작업은 우리가 스스로 완성하고 싶지 않다. 우리는 쓰레기 수집기에게 HashMap
중의 HashMap
대상만 인용하고 있는 상황에서 상응하는 key
대상을 회수할 수 있다고 알려주고 싶다.분명히 앞의 약인용의 정의에 따라 약인용을 사용하면 우리가 이 목적을 달성하는 데 도움을 줄 수 있다.우리는 단지 Product
대상을 가리키는 약한 인용 대상을 Product
중의 Product
로 하면 된다.3. How―약한 인용을 어떻게 사용합니까?
위에서 소개한 장면을 예로 들면 우리는
HashMap
대상을 가리키는 약한 인용 대상을 key
의Product
로 사용한다. 이 약한 인용 대상을 이렇게 정의하기만 하면 된다.
Product productA = new Product(...);
WeakReference<Product> weakProductA = new WeakReference<>(productA);
현재 인용 대상HashMap
은 key
대상weakProductA
을 가리킨다.그러면 우리는 어떻게 Product
를 통해 그것이 가리키는 productA
대상weakProduct
을 얻을 수 있습니까?간단합니다. 아래 코드만 있으면 됩니다.
Product product = weakProductA.get();
실제로 이런 상황에 대해 자바 라이브러리는 우리에게 Product
클래스를 제공했다. 사용과 이 클래스의 키는 자연히 약한 인용 대상이기 때문에 우리가 원시 대상을 수동으로 포장할 필요가 없다.이렇게 되면 productA
이 WeakHashMap
로 변할 때 (인용된 productA
메모리에 존재할 필요가 없음을 나타낸다) 이때 이 null
대상을 가리키는 것은 약한 인용 대상Product
이 된다. 그러면 분명히 이때 해당하는 Product
대상이 약할 수 있기 때문에 약한 인용을 가리키는 것은 제거되고 이 weakProductA
대상은 회수된다.그것을 가리키는 약한 인용 대상은 인용 대기열에 들어갑니다.4. 참조 대기열
다음은 인용 대열의 개념을 간단하게 소개합니다.실제로
Product
클래스에는 다음과 같은 두 가지 구조 함수가 있습니다.
//
WeakReference(T referent)
//
WeakReference(T referent, ReferenceQueue<? super T> q)
우리는 두 번째 구조 방법에서 Product
유형의 매개 변수를 제공한 것을 볼 수 있다. 이 매개 변수를 제공함으로써 우리는 만들어진 약한 인용 대상을 하나의 인용 대기열에 등록했다. 이렇게 하면 쓰레기 수거기에 의해 제거될 때 이 인용 대기열에 보내서 제거된 약한 인용 대상을 통일적으로 관리할 수 있다.5. 총결산
자, 이 글의 내용은 여기까지 끝났습니다. 개인의 수준이 제한되어 있기 때문에 서술에서 부정확하거나 명확하지 않은 부분이 존재하지 않을 수 없습니다. 여러분이 저희에 대한 지지에 감사드린다고 지적해 주시기 바랍니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
38. Java의 Leetcode 솔루션텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.