자바 의 소프트 인용 과 약 인용
5730 단어 자바 중급 편
억지로 인용 하 다
new 를 통 해 얻 은 메모리 공간 을 가리 키 는 인용 을 강 인용 이 라 고 합 니 다.예 를 들 어 String a=new String("123")입 니 다.그 중에서 a 는 강 한 인용 입 니 다.메모리 가 123 인 공간 을 가리 키 고 있 습 니 다.평소에 우리 가 가장 많이 쓰 는 것 도 강 한 타 입 이다.
소프트 인용
소프트 인용(자바 에서 SoftReference 류 로 구현 가능)은 한 대상 이 소프트 인용 이 있 으 면 가상 컴퓨터 메모리 가 부족 하거나 oom 이 발생 하기 전에 JVM 가상 기 회 는 소프트 인용 이 가리 키 는 메모리 영역 을 회수 하고 메모리 가 충분 하면 회수 하지 않 는 다 는 뜻 이다.일반적으로 비교적 민감 한 정 보 를 저장 하 는 데 쓰 인 다.
약 인용
약 한 인용 과 부 드 러 운 인용 은 비교적 잘 알 고 있 습 니 다(Weak Reference 류 를 통 해 이 루어 집 니 다).쓰레기 수 거 기 는 특정한 메모리 에 있 고 약 한 인용 만 있 는 것 을 발견 하면(약 한 인용 만 있 고 강 한 인용 이 없 음 을 주의해 야 합 니 다)이 메모리 의 주소 공간 을 가리 키 고 있 습 니 다.현재 메모리 가 충분 하 든 약 한 인용 이 가리 키 는 메모리 공간 은 GC 에서 회수 합 니 다.
거짓 인용
가상 인용 은 환상 인용 이 라 고도 합 니 다.Phantom Reference 류 를 통 해 이 루어 집 니 다.방문 대상 의 모든 속성 과 함 수 를 가상 인용 할 수 없습니다.가상 인용 은 대상 이 finalize 이후 에 어떤 일 을 할 수 있 도록 하 는 체 제 를 제공 할 뿐 입 니 다.(현재 학습 단계 에 서 는 그것 을 어떻게 사용 하 는 지 접 하지 못 했 으 며,이후 에 만나면 다시 한 편 을 보충 합 니 다)
다음은 이 부 드 러 운 인용 과 약 한 인용 사이 의 차 이 를 살 펴 보 자.
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
/**
*
*
* @author koala
* @date 2018/5/26
*/
public class ReferenceDemo {
public static void main(String[] args) {
/**
* str abc
*/
String str = new String("abc");
//
SoftReference softReference = new SoftReference(str);
str = null;
System.gc();
System.out.println(softReference.get()); // : abc
String abc = new String("123");
//
WeakReference weekReference = new WeakReference(abc);
//
abc = null;
System.gc();
System.out.println(weekReference.get()); // : null
}
}
일반적으로 소프트 인용 은 캐 시 처 리 를 할 수 있 습 니 다.제3자 캐 시 체 제 를 사용 하지 않 으 면 소프트 인용 으로 캐 시 방안 을 실현 할 수 있 습 니 다.예 를 들 어 글 캐 시(소프트 인용 에서 글 내용 을 가 져 오고 데이터 베이스 에서 가 져 오지 않 으 면 소프트 인용 으로 되 돌 릴 수 있 습 니 다)
우 리 는 Weak HashMap 을 사용 하여 약 한 인용 사용 장면 을 알 아 보 겠 습 니 다.
“` import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap;
/***약 인용 대상**@author koala*@date 2018/5/26*/
public class WeekHashMapDemo {
public static void main(String[] args) {
/**
* // 1000 A
*
* a -> A
*
*/
String a = new String("ABC");
/**
* // 2000 B
*
* b -> B
*
*/
String b = new String("123");
Map weakMap = new WeakHashMap();
Map map = new HashMap(10);
/**
* a - > A --
* map:(AAA) - > A --
*
* b - > B --
* map: (BBB) - > B --
*/
map.put(a,"AAA");
map.put(b,"BBB");
/**
* a - > A --
* map:(AAA) - > A --
* weakmap:(aaa) -> A --
*
* b - > B --
* map: (BBB) - > B --
* weakmap:(bbb) -> B --
*/
weakMap.put(a,"aaa");
weakMap.put(b,"bbb");
/**
* a - > A --
* weakmap:aaa -> A --
*
* b - > B --
* map: BBB - > B --
* weakmap:bbb -> B --
*/
map.remove(a);
/**
* weakmap:aaa -> A --
*
* map: BBB - > B --
* weakmap:bbb -> B --
*/
a = null;
b = null;
System.gc();
/**
*
* map,123:BBB
*
* , gc ,map a , b
*/
System.out.println(a);
Iterator i = map.entrySet().iterator();
while (i.hasNext()){
Map.Entry en = (Map.Entry) i.next();
System.out.println("map,"+en.getKey()+":"+en.getValue());
}
/**
*
* weakmap,123:bbb
*
* :weakmap key a ( A) ,gc , A (A )
* weakmap key b , map B, weakmap key b , ,
*
*/
Iterator j = weakMap.entrySet().iterator();
while (j.hasNext()){
Map.Entry en = (Map.Entry) j.next();
System.out.println("weakmap,"+en.getKey()+":"+en.getValue());
}
}
}
부 드 러 운 인용 이 든 약 한 인용 이 든 허 인용 을 가 져 오 는 것 은 인용 대기 열 Reference Queue 를 사용 하여 사용 할 수 있 습 니 다.프로그램 을 통 해 일부 인용 이 추가 되 었 는 지 여 부 를 판단 할 수 있 습 니 다.그 인용 은 회수 되 었 습 니 다.따라서 우 리 는 인용 회수 전에 프로그램 행동 을 취 할 수 있 습 니 다.