Java에서 SoftReference와 WeakReference의 차이점은 무엇입니까?
java.lang.ref.WeakReference
과 의 차이점은 무엇입니까 java.lang.ref.SoftReference
?
에서 이해 약한 참조 에단 니콜라스에 의해 :
약한 참조
약한 참조 , 간단히 넣어, 메모리에 남아있는 개체를 강제로 강한 것만으로는 충분하지 않습니다 참조입니다. 약한 참조를 사용하면 가비지 수집기의 기능을 활용하여 도달 가능성을 결정할 수 있으므로 직접 수행 할 필요가 없습니다. 다음과 같이 약한 참조를 만듭니다.
WeakReference weakWidget = new WeakReference(widget);
코드의 다른 곳에서
weakWidget.get()
실제Widget
객체 를 가져 오는 데 사용할 수 있습니다 . 물론 약한 참조는 가비지 수집을 막을만큼 충분히 강력하지 않으므로weakWidget.get()
갑자기를 반환하기 시작 하는 (위젯에 대한 강력한 참조가없는 경우) 찾을 수 있습니다null
....
소프트 참조
소프트 참조는 참조하는 객체를 버릴 이하 열망하는 것을 제외하고, 정확히 약한 참조 같다. 약하게 도달 할 수있는 객체 (가장 강력한 참조는
WeakReferences
)는 다음 가비지 수집주기에서 버려지지만 부드럽게 도달 할 수있는 객체는 일반적으로 잠시 동안 붙어 있습니다.
SoftReferences
와 다르게 동작 할 필요 는 없지만WeakReferences
실제로는 부드럽게 도달 할 수있는 객체는 일반적으로 메모리가 충분히 공급되는 한 유지됩니다. 이렇게하면 위에서 설명한 이미지 캐시와 같은 캐시의 훌륭한 기반이됩니다. 가비지 수집기가 객체에 도달 할 수있는 정도 (강하게 도달 할 수있는 객체는 캐시에서 제거 되지 않음 )와 얼마나 나쁜지 둘 다에 대해 걱정하게 할 수 있기 때문입니다. 그들이 소비하는 메모리가 필요합니다.
그리고 Peter Kessler는 다음과 같이 댓글을 달았습니다.
Sun JRE는 SoftReference를 WeakReference와 다르게 취급합니다. 사용 가능한 메모리에 부담이없는 경우 SoftReference에서 참조하는 객체를 유지하려고합니다. 한 가지 세부 사항 : "-client"및 "-server"JRE에 대한 정책은 다릅니다. -client JRE는 힙을 확장하는 대신 SoftReferences를 지우는 것을 선호하여 풋 프린트를 작게 유지하려고하지만 -server JRE는 SoftReferences를 지우는 대신 힙 (가능한 경우)을 확장하는 것을 선호하여 성능을 높입니다. 하나의 크기가 모든 것에 맞지는 않습니다.
약한 참조는 열심히 수집됩니다. GC가 개체가 약하게 접근 할 수 있음을 발견하면 (약한 참조를 통해서만 접근 할 수 있음) 해당 개체에 대한 약한 참조를 즉시 지 웁니다. 따라서 클래스에 대한 캐시 된 리플렉션 정보 나 개체에 대한 래퍼 등과 같이 프로그램이 "관련된 정보"를 유지하는 (강력하게 참조되는) 개체에 대한 참조를 유지하는 데 좋습니다. 연관된 객체가 GC로 처리 된 후에는 유지할 의미가 없습니다. 약한 참조가 지워지면 코드가 어딘가에 폴링하는 참조 대기열에 추가되고 관련 객체도 삭제됩니다. 즉, 객체에 대한 추가 정보를 유지하지만 참조하는 객체가 사라지면 해당 정보는 필요하지 않습니다. 사실은, 특정 상황에서는 WeakReference를 하위 클래스로 만들고 WeakReference 하위 클래스의 필드에 객체에 대한 관련 추가 정보를 유지할 수도 있습니다. WeakReference의 또 다른 일반적인 사용은 표준 인스턴스를 유지하기 위해 Maps와 함께 사용하는 것입니다.
반면에 SoftReferences는 GC가 일반적으로 삭제를 지연하므로 외부의 재생성 가능한 리소스를 캐싱하는 데 좋습니다. OutOfMemoryError가 발생하기 전에 모든 SoftReference가 지워지는 것이 보장되므로 이론적으로 OOME [*]이 발생할 수 없습니다.
일반적인 사용 사례 예는 파일에서 구문 분석 된 형태의 콘텐츠를 유지하는 것입니다. 파일을로드하고 파싱하고 파싱 된 표현의 루트 객체에 대한 SoftReference를 유지하는 시스템을 구현할 것입니다. 다음에 파일이 필요할 때 SoftReference를 통해 검색을 시도합니다. 검색 할 수 있다면 다른로드 / 파싱을 아끼고 GC가 그 동안 삭제했다면 다시로드합니다. 이렇게하면 성능 최적화를 위해 여유 메모리를 사용하지만 OOME 위험은 없습니다.
이제 [*]입니다. SoftReference를 유지하는 것은 그 자체로 OOME을 유발할 수 없습니다. 반면에 WeakReference가 사용되는 작업에 SoftReference를 실수로 사용하는 경우 (즉, 어떤 방식 으로든 강력하게 참조 된 Object와 관련된 정보를 유지하고 Reference 객체가 지워지면 삭제) OOME을 다음과 같이 실행할 수 있습니다. ReferenceQueue를 폴링하고 관련 객체를 삭제하는 코드가 적시에 실행되지 않을 수 있습니다.
따라서 결정은 사용량에 따라 달라집니다. 구성하는 데 비용이 많이 들지만 그럼에도 불구하고 다른 데이터에서 재구성 할 수있는 정보를 캐싱하는 경우 소프트 참조를 사용하십시오. 일부 데이터의 표준 인스턴스에 대한 참조를 유지하거나 원하는 경우 "소유"하지 않고 객체에 대한 참조가 있으면 (따라서 GC가되지 않도록) 약한 참조를 사용하십시오.
자바에서 ; 가장 강한 것부터 가장 약한 것 순으로 : Strong, Soft, Weak 및 Phantom
강한 참조는 GC에 의해 수집에서 언급 된 목적을 보호하는 정상 기준이다. 즉 절대 쓰레기 수거하지 마십시오.
소프트 참조는 가비지 컬렉터에 의해 수집 대상이지만, 아마도 메모리가 필요할 때까지 수집되지 않습니다. 즉, 가비지가 전에 수집 OutOfMemoryError
됩니다.
약한 참조는 GC에 의해 수집에서 참조 된 개체를 보호하지 않는 기준이다. 즉 Strong 또는 Soft ref가 없을 때 가비지가 수집됩니다.
팬텀 참조는 객체에 대한 참조 phantomly가 확정 된 후에 언급하지만, 그 할당 된 메모리는 회수되기 이전이다.
비유 : JVM은 왕국, Object는 왕국의 왕, GC는 왕 (객체)을 죽이려는 왕국의 공격 자라고 가정합니다.
- King이 Strong 일 때 GC는 그를 죽일 수 없습니다.
- King is Soft , GC 는 그를 공격하지만 King은 자원을 사용할 수있을 때까지 보호를 통해 왕국을 지배합니다.
- King is Weak , GC 는 그를 공격하지만 보호없이 왕국을 지배합니다.
- king이 Phantom 일 때 GC는 이미 그를 죽 였지만 그의 영혼을 통해 왕을 사용할 수 있습니다.
약한 참조 http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html
원칙 : weak reference
가비지 수집과 관련이 있습니다. 일반적으로 하나 이상의 객체를 가진 객체 reference
는 가비지 수집 대상이 아닙니다.
위의 원칙은 적용되지 않습니다 weak reference
. 개체에 다른 개체와의 약한 참조 만있는 경우 가비지 수집 준비가 된 것입니다.
아래 예제를 살펴 보겠습니다 Map
. 키가 객체를 참조 하는 with Objects가 있습니다.
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> aMap = new
HashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
System.out.println("Size of Map" + aMap.size());
}
}
이제 프로그램을 실행하는 동안 emp = null
. Map
그대로 유지 키 여기에 이해되지 않는다 null
. 위의 상황에서 개체는 가비지 수집되지 않습니다.
WeakHashMap
WeakHashMap
에서 key-to-value mappings
더 이상 검색 할 수 없을 때 항목 ( )이 제거되는 곳입니다 Map
.
Let me show the above example same with WeakHashMap
import java.util.WeakHashMap;
public class Test {
public static void main(String args[]) {
WeakHashMap<Employee, EmployeeVal> aMap =
new WeakHashMap<Employee, EmployeeVal>();
Employee emp = new Employee("Vinoth");
EmployeeVal val = new EmployeeVal("Programmer");
aMap.put(emp, val);
emp = null;
System.gc();
int count = 0;
while (0 != aMap.size()) {
++count;
System.gc();
}
System.out.println("Took " + count
+ " calls to System.gc() to result in weakHashMap size of : "
+ aMap.size());
}
}
Output: Took 20 calls to System.gc()
to result in aMap size
of : 0.
WeakHashMap
has only weak references to the keys, not strong references like other Map
classes. There are situations which you have to take care when the value or key is strongly referenced though you have used WeakHashMap
. This can avoided by wrapping the object in a WeakReference.
import java.lang.ref.WeakReference;
import java.util.HashMap;
public class Test {
public static void main(String args[]) {
HashMap<Employee, EmployeeVal> map =
new HashMap<Employee, EmployeeVal>();
WeakReference<HashMap<Employee, EmployeeVal>> aMap =
new WeakReference<HashMap<Employee, EmployeeVal>>(
map);
map = null;
while (null != aMap.get()) {
aMap.get().put(new Employee("Vinoth"),
new EmployeeVal("Programmer"));
System.out.println("Size of aMap " + aMap.get().size());
System.gc();
}
System.out.println("Its garbage collected");
}
}
Soft References.
Soft Reference
is slightly stronger that weak reference. Soft reference allows for garbage collection, but begs the garbage collector to clear it only if there is no other option.
The garbage collector does not aggressively collect softly reachable objects the way it does with weakly reachable ones -- instead it only collects softly reachable objects if it really "needs" the memory. Soft references are a way of saying to the garbage collector, "As long as memory isn't too tight, I'd like to keep this object around. But if memory gets really tight, go ahead and collect it and I'll deal with that." The garbage collector is required to clear all soft references before it can throw OutOfMemoryError
.
The only real difference between a soft reference and a weak reference is that
the garbage collector uses algorithms to decide whether or not to reclaim a softly reachable object, but always reclaims a weakly reachable object.
SoftReference
is designed for caches. When it is found that a WeakReference
references an otherwise unreachable object, then it will get cleared immediately. SoftReference
may be left as is. Typically there is some algorithm relating to the amount of free memory and the time last used to determine whether it should be cleared. The current Sun algorithm is to clear the reference if it has not been used in as many seconds as there are megabytes of memory free on the Java heap (configurable, server HotSpot checks against maximum possible heap as set by -Xmx
). SoftReference
s will be cleared before OutOfMemoryError
is thrown, unless otherwise reachable.
This article can be super helpful to understand strong, soft, weak and phantom references.
To give you a summary,
If you only have weak references to an object (with no strong references), then the object will be reclaimed by GC in the very next GC cycle.
If you only have soft references to an object (with no strong references), then the object will be reclaimed by GC only when JVM runs out of memory.
So you can say that, strong references have ultimate power (can never be collected by GC)
Soft references are powerful than weak references (as they can escape GC cycle until JVM runs out of memory)
Weak references are even less powerful than soft references (as they cannot excape any GC cycle and will be reclaimed if object have no other strong reference).
Restaurant Analogy
- Waiter - GC
- You - Object in heap
- Restaurant area/space - Heap space
- New Customer - New object that wants table in restaurant
Now if you are a strong customer (analogous to strong reference), then even if a new customer comes in the restaurant or what so ever happnes, you will never leave your table (the memory area on heap). The waiter has no right to tell you (or even request you) to leave the restaurant.
If you are a soft customer (analogous to soft reference), then if a new customer comes in the restaurant, the waiter will not ask you to leave the table unless there is no other empty table left to accomodate the new customer. (In other words the waiter will ask you to leave the table only if a new customer steps in and there is no other table left for this new customer)
If you are a weak customer (analogous to weak reference), then waiter, at his will, can (at any point of time) ask you to leave the restaurant :P
The Only Real Difference
Per the doc, loose WeakReferences must be cleared by a running GC.
Per the doc, loose SoftReferences must be cleared before OOM is thrown.
That's the only real difference. Everything else is not part of the contract. (I'll assume the latest docs are contractual.)
SoftReferences are useful. Memory-sensitive caches use SoftReferences, not WeakReferences.
WeakReference 의 유일한 적절한 사용은 GC 실행을 관찰하는 것입니다. 객체가 즉시 범위를 벗어나는 새로운 WeakReference를 생성하여이를 수행 한 다음
weak_ref.get()
. 이 때
null
, 당신은이 기간, GC가 실행 된 사이에 그 내용.
WeakReference의 잘못된 사용에 관해서 는 목록이 끝이 없습니다.
a lousy hack to implement priority-2 softreference such that you don't have to write one, yet it doesn't work as expected because the cache would be cleared on every GC run, even when there is spare memory. See https://stackoverflow.com/a/3243242/632951 for phails. (Besides, what if you need more than 2 levels of cache priority? You'd still gotta need a real library for it.)
a lousy hack to associate data with an object of an existing class, yet it creates a memory leak (OutOfMemoryError) when your GC decides to take a break after your weakreferences are created. Besides, it's beyond ugly: A better approach is to use tuples.
a lousy hack to associate data with an object of an existing class, where the class has the nerve to make itself non-subclassable, and is used in an existing function code which you need to call. In such a case, the proper solution is to either edit the class and make it subclassable, or edit the function and make it take an interface instead of a class, or use an alternative function.
The six types of object reachability states in Java -
- Strongly reachable objects - GC will not collect (reclaim the memory occupied by) this kind of objects. These are reachable via a root node or another strongly reachable object (i.e. via local variables, class variables, instance variables etc.)
- Softly reachable objects - GC may attempt to collect this kind of objects depending on memory contention. These are reachable from the root via one or more soft reference objects
- Weakly reachable objects - GC must collect this kind of objects. These are reachable from the root via one or more weak reference objects
- Resurrect-able objects - GC is already in the process of collecting these objects. But they may go back to one of the states - Strong/Soft/Weak by the execution of some finalizer
- Phantomly reachable object - GC is already in the process of collecting these objects and has determined to not be resurrect-able by any finalizer (if it declares a finalize() method itself, then its finalizer will have been run). These are reachable from the root via one or more phantom reference objects
- Unreachable object - An object is neither strongly, softly, weakly, nor phantom reachable, and is not resurrectable. These objects are ready for reclamation
For more details: https://www.artima.com/insidejvm/ed2/gc16.html « collapse
One should be aware that a weakly referenced object will only get collected when it has ONLY weak reference(s). If it has so much as one strong reference, it does not get collected no matter how many weak references it has.
WeakReference: objects that are only weakly referenced are collected at every GC cycle (minor or full).
SoftReference: when objects that are only softly referenced are collected depends on:
-XX:SoftRefLRUPolicyMSPerMB=N flag (default value is 1000, aka 1 second)
Amount of free memory in the heap.
Example:
- heap has 10MB of free space (after full GC);
- -XX:SoftRefLRUPolicyMSPerMB=1000
Then object which is referenced only by SoftReference will be collected if last time when it was accessed is greater then 10 seconds.
To give an in-action memory usage aspect, I did an experiment with Strong, Soft, Weak & Phantom references under heavy load with heavy objects by retaining them till end of program. Then monitored heap usage & GC behavior. These metrics may vary case by case basis but surely gives high level understanding. Below are findings.
Heap & GC Behavior under heavy load
- Strong/Hard Reference - As program continued, JVM couldn't collect retained strong referenced object. Eventually ended up in "java.lang.OutOfMemoryError: Java heap space"
- Soft Reference - As program continued, heap usage kept growing, but OLD gen GC happened hen it was nearing max heap. GC started bit later in time after starting program.
- Weak Reference - As program started, objects started finalizing & getting collected almost immediately. Mostly objects got collected in young generation garbage collection.
- Phantom Reference - Similar to weak reference, phantom referenced objects also started getting finalized & garbage collected immediately. There were no old generation GC & all objects were getting collected in young generation garbage collection itself.
You can get more in depth graphs, stats, observations for this experiment here.
'code' 카테고리의 다른 글
Markdown에서 이미지 크기 변경 (0) | 2020.09.29 |
---|---|
픽셀을 dp로 변환 (0) | 2020.09.29 |
비어 있지 않은 폴더를 제거 / 삭제하려면 어떻게합니까? (0) | 2020.09.29 |
글로벌 Git 무시 (0) | 2020.09.29 |
Java "Double Brace Initialization"의 효율성? (0) | 2020.09.29 |