각각에 개념부터.
- WeakReference
- 말그대로, '약한' 참조 이다. '약한' 참조는 해당 객체에 대한 소멸을 막지 않는다. 즉, 어떤 객체에 대한 참조가 WeakReference 밖에 남아있지 않다면 그 객체는 gc(Garbage Collection) 의 대상이 된다.
-
펼치기 - J2SE 5.0 api 문서의 설명 원문
Weak reference objects, which do not prevent their referents from being made finalizable, finalized, and then reclaimed. Weak references are most often used to implement canonicalizing mappings.
Suppose that the garbage collector determines at a certain point in time that an object is weakly reachable. At that time it will atomically clear all weak references to that object and all weak references to any other weakly-reachable objects from which that object is reachable through a chain of strong and soft references. At the same time it will declare all of the formerly weakly-reachable objects to be finalizable. At the same time or at some later time it will enqueue those newly-cleared weak references that are registered with reference queues.
- SoftReference
- WeakReference 보다는 약간 강한 참조이다. Soft reference 만 남아있는 객체는 메모리의 요청에 의한 gc 의 대상이 된다. 메모리의 남은 공간이 넉넉하다면 gc되지 않을 것이며, 메모리의 남은 공간이 얼마 없거나 하다면 gc 의 대상이 될 것이다.
확실한건 vm 이 OutOfMemoryError 를 발생시키기 전에는 Soft reference 만 남아있는 객체가 gc의 대상이 된다는 점 정도고, 그 이외에는 vm 의 구현에 따라 다를 수 있다. -
펼치기 - J2SE 5.0 api 문서의 설명 원문
Soft reference objects, which are cleared at the discretion of the garbage collector in response to memory demand. Soft references are most often used to implement memory-sensitive caches.
Suppose that the garbage collector determines at a certain point in time that an object is softly reachable. At that time it may choose to clear atomically all soft references to that object and all soft references to any other softly-reachable objects from which that object is reachable through a chain of strong references. At the same time or at some later time it will enqueue those newly-cleared soft references that are registered with reference queues.
All soft references to softly-reachable objects are guaranteed to have been cleared before the virtual machine throws an
OutOfMemoryError
. Otherwise no constraints are placed upon the time at which a soft reference will be cleared or the order in which a set of such references to different objects will be cleared. Virtual machine implementations are, however, encouraged to bias against clearing recently-created or recently-used soft references.Direct instances of this class may be used to implement simple caches; this class or derived subclasses may also be used in larger data structures to implement more sophisticated caches. As long as the referent of a soft reference is strongly reachable, that is, is actually in use, the soft reference will not be cleared. Thus a sophisticated cache can, for example, prevent its most recently used entries from being discarded by keeping strong referents to those entries, leaving the remaining entries to be discarded at the discretion of the garbage collector.
샘플 코드를 보자.
//테스트용 클래스. 별거 없다.
public static class Inner {
public String str;
public Inner(String value) {
this.str = value;
}
public String getStr(){
return this.str;
}
public String toString() {
return this.str;
}
}
public static void main(String[] args) {
try{
//일반 참조. 객체를 그냥 생성해서 리스트에 넣고 gc 한다.
List<Inner> tmpList = new ArrayList<Inner>();
tmpList.add(new Inner("simple reference is alive."));
System.gc();
// gc 후 객체가 살아있는지 확인한다.
for (Inner refer : tmpList) {
if (refer == null) {
System.out.println("refer is null.");
}else {
System.out.println(refer.getStr());
}
}
//WeakReference.
List<WeakReference> list = new ArrayList<WeakReference>();
WeakReference<Inner> wr = new WeakReference<Inner>( new Inner("weak reference test obj is alive."));
list.add(wr);
//gargage collention 발생.
System.gc();
//gc 후 객체가 살아있는지 확인한다.
for (WeakReference<Inner> refer : list) {
if (refer == null) {
System.out.println("refer is null.");
}else {
Inner inner = refer.get();
if (inner == null) {
System.out.println("referenced obj is null.");
}else
System.out.println(inner.getStr());
}
}
//SoftReference.
List<SoftReference> slist = new ArrayList<SoftReference>();
SoftReference<Inner> sr = new SoftReference<Inner>( new Inner("soft reference test obj is alive."));
slist.add(sr);
System.gc();
//gc 후 객체가 살아있는지 확인한다.
for (SoftReference<Inner> refer : slist) {
if (refer == null) {
System.out.println("refer is null.");
}else {
Inner inner = refer.get();
if (inner == null) {
System.out.println("referenced obj is null.");
}else
System.out.println(inner.getStr());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
위 코드는 간단한 테스트 코드로, 리스트에 일반적인 참조, WeakReference, SoftReference 로 add 한후, gc 를 실행시킨뒤 리스트에 객체에 대한 참조가 남아있는지 (생성한 객체가 gc 되었는지) 를 확인하는 코드이다.
실행시켜보면 다음과 같이 찍힌다.
referenced obj is null.
soft reference test obj is alive.
WeakReference 로 참조한 객체만 gc 되서 null 이 찍힌다. jdk 버전등에 따라 결과가 다를 수도 있겠지만, 테스트코드만 돌리는 상황이라면 메모리 여유공간은 아마 넉넉할 것이므로, 대체로 같은 결과일 것이다.
출처 : http://jaguarmk.tistory.com/25
'프로그래밍 > 자바' 카테고리의 다른 글
Java - JSONObject에서 element와 accumulate 차이점 (0) | 2017.09.16 |
---|---|
Java - StringBuilder 사용하기 (0) | 2015.08.08 |
OutputStream flush의 역할 (0) | 2013.12.07 |
[Java] WeakReference 와 SoftReference 의 차이점. (0) | 2013.12.05 |
Enumeration 클래스와 ListIterator 클래스 (0) | 2012.08.13 |