development

자바 : 강 / 약 / 약 / 팬텀 참조의 차이점

big-blog 2020. 6. 1. 08:20
반응형

자바 : 강 / 약 / 약 / 팬텀 참조의 차이점


주제에 대한 이 기사읽었 지만 실제로 이해하지 못합니다. 개념을 설명 할 때 예제와 함께 조언을 해주십시오.


자바는 서로 다른 두 가지 유형을 제공합니다 /의 클래스 참조 개체 : 강력한약한 . 약한 참조 객체는 소프트팬텀 으로 더 나눌 수 있습니다 . 하나씩 살펴 보자.

강력한 참조 객체

StringBuilder builder = new StringBuilder();

다르게 지정되지 않은 경우 이것은 참조 객체의 기본 유형 / 클래스입니다 builder. 강력한 참조 객체입니다. 이러한 종류의 참조는 참조 된 개체가 GC에 적합하지 않게합니다. 즉, 강력한 참조 객체 체인으로 객체를 참조 할 때마다 가비지 수집 할 수 없습니다.

약한 참조 객체

WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);

약한 참조 객체는 참조 객체의 기본 유형 / 클래스가 아니며 사용하려면 위의 예와 같이 명시 적으로 지정해야합니다. 이런 종류의 참조는 참조 객체를 GC에 적합하게 만듭니다. 즉, StringBuilder메모리 에서 객체에 도달 할 수있는 유일한 참조 가 실제로 약한 참조 인 경우 GC는 StringBuilder객체 를 가비지 수집 할 수 있습니다. 메모리에있는 객체에 약한 참조 객체 만 도달 할 수있는 경우 자동으로 GC에 적합합니다.

약점

softphantom 의 두 가지 다른 수준의 약점이 참여할 수 있습니다 .

소프트 메모리를 사용할 수 있으며의 위험이 없을 때까지 통상은 GC 사이클 저항 : 목표물 기본적 메모리 A의 남아 이상의 비트 것을 약한 목표물이다 OutOfMemoryError(이 경우에는, 제거 할 수)가.

반면, 팬텀 참조 객체는 객체가 메모리에서 효과적으로 제거 된 시점을 정확히 아는 경우에만 유용합니다. 일반적으로 객체는 실제로 객체 자체를 반환하지 않지만 이상한 finalize () 부흥 / 부활 동작 을 수정하는 데 사용됩니다. 메모리 존재를 추적하는 데 도움이 됩니다 .

약한 참조 객체는 캐시 모듈을 구현하는 데 이상적입니다. 사실, 강력한 참조 체인으로 객체 / 값에 더 이상 도달 할 수 없을 때마다 GC가 메모리 영역을 정리할 수 있도록하여 일종의 자동 제거를 구현할 수 있습니다. 약한 키를 유지 하는 WeakHashMap 이 그 예입니다 .


약한 참조 :

간단히 말해서 약한 참조는 객체를 메모리에 유지하기에 충분히 강하지 않은 참조입니다. 약한 참조를 사용하면 가비지 수집기의 도달 가능성을 결정하는 기능을 활용할 수 있으므로 직접 할 필요가 없습니다.

소프트 레퍼런스 :

소프트 참조는 참조하는 개체를 버리고 싶어한다는 점을 제외하고는 약한 참조와 같습니다. 다음 가비지 수집주기에서 약하게 도달 할 수있는 개체 (가장 약한 참조는 약한 참조)는 삭제되지만 일반적으로 부드럽게 도달 할 수있는 개체는 잠시 동안 고정됩니다.

팬텀 레퍼런스 :

팬텀 참조는 SoftReference 또는 WeakReference와 상당히 다릅니다. 객체의 그립은 너무 작아서 객체를 검색 할 수 없습니다. get () 메서드는 항상 null을 반환합니다. 이러한 참조에 대한 유일한 사용은 참조 된 오브젝트가 죽은 것으로 알고있는 시점에서 ReferenceQueue에 큐에 들어가는 시점을 추적하는 것입니다.

이 텍스트는 https://weblogs.java.net/blog/2006/05/04/understanding-weak-references 에서 추출되었습니다.


사이의 간단한 차이 SoftReference와는 WeakReference에서 제공하는 안드로이드 개발자 .

a SoftReference와 a 의 차이점 WeakReference은 참조를 지우고 대기열에 넣기로 결정한 시점입니다.

  • SoftReference가급적 늦게 (즉, VM에 메모리 부족이 발생할 위험이있는 경우) A 를 지우고 큐에 넣어야합니다.

  • WeakReference약한 참조로 알려진 즉시 A를 지우고 큐에 넣을 수 있습니다.


사용한 세 가지 용어는 주로 가비지 수집 대상의 오브젝트 자격과 관련이 있습니다.

약한 참조 :: 객체가 메모리에 남아있게하기에 충분히 강하지 않은 참조입니다. 그것 가비지 컬렉터의 변덕은 가비지 컬렉션 객체를 수집합니다. GC가이를 수집하지 않도록 강요 할 수는 없습니다 .

Soft Reference :: 약한 참조와 거의 비슷합니다. 그러나 가비지 수집의 약한 참조보다 개체를 조금 더 강력하게 보유한다고 말할 수 있습니다.

가비지 콜렉터가 첫 번째 라이프 사이클 자체에서 약한 참조를 수집하면 다음 가비지 콜렉션주기에서 소프트 참조를 수집합니다.

강력한 참조 :: 위의 두 종류의 참조와 반대입니다. 그들은 쓰레기를 수집하는 것을 좋아하지 않습니다 (대부분 그들은 결코 수집되지 않습니다).

자세한 정보는 다음 링크를 참조하십시오.

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html


4도 참조- Strong, Weak, Soft, Phantom

강력-일종의 참조이므로 참조 된 개체가 GC에 적합하지 않습니다. 빌더 클래스. 예-StringBuilder

약함-GC에 적합한 참조입니다.

소프트-메모리가 사용 가능할 때까지 오브젝트가 GC에 적합한 일종의 참조입니다. 이미지 캐시에 적합합니다. 메모리를 사용할 수있을 때까지 보관합니다.

팬텀 (Phantom)-객체가 GC에 직접 적합한 레퍼런스의 일종입니다. 객체가 메모리에서 제거 될 때만 알 수 있습니다.

사용합니다 :

  1. 객체가 메모리에서 정확히 제거되는 시점을 식별 할 수 있습니다.

  2. when finalize() method is overloaded, then GC might not happen in timely fashion for GC eligible objects of the two classes. So phantom reference makes them eligible for GC before finalize(), is why you can get OutOfMemoryErrors even when most of the heap is garbage.

Weak references are ideal to implement the cache modules.


This article can be super helpful to understand strong, soft, weak and phantom references.


To give you a summary,

If you have a strong reference to an object, then the object can never be collected/reclaimed by GC (Garbage Collector).

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.

We create phantom references to an object to keep track of when the object gets enqueued into the ReferenceQueue. Once you know that you can perform fine-grained finalization. (This would save you from accidentally resurrecting the object as phantom-reference don't give you the referrant). I'd suggest you reading this article to get in-depth detail about this.


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


Strong References

These are your regular object references which we code daily:

Employee emp = new Employee();

The variable “emp” holds a strong reference to an Employee object and objects that are reachable through any chain of strong references are not eligible for garbage collection. Usually, this is what you want but not always. Now suppose we are fetching lots of employees from database in a collection or map, and we need to do a lot of processing on them regularly, So in order keep performance we will keep them in the cache.

As far as this is good but now we need different data and we don’t need those Employee objects and these are not referenced from anywhere except the cache. Which is causing a memory leak because these objects are not in use but still not eligible for the garbage collection and we cannot remove those objects from cache because we don’t have reference to them? So here either we need to empty the entire cache manually which is tedious or we could use other kind references e.g. Weak References.

Weak References

A weak reference does not pin an object into memory and will be GC’d in next GC cycle if not referenced from other references. We can use WeakReference class which is provided by Java to create above kind of caches, which will not store objects which are not referenced from somewhere else.

WeakReference<Cache> cache = new WeakReference<Cache>(data);

To access data you need to call cache.get(). This call to get may return null if the weak reference was garbage collected: you must check the returned value to avoid NPEs. Java provides collections that use weak references e.g., the WeakHashMap class stores keys (not values) as weak references. If the key is GC’d then the value will automatically be removed from the map too.

Since weak references are objects too we need a way to clean them up (they’re no longer useful when the object they were referencing has been GC’d). If you pass a ReferenceQueue into the constructor for a weak reference then the garbage collector will append that weak reference to the ReferenceQueue before they’re finalized or GC’d. You can periodically process this queue and deal with dead references.

Soft References

A SoftReference is like a WeakReference but it is less likely to be garbage collected. Soft references are cleared at the discretion of the garbage collector in response to memory demand. The virtual machine guarantees that all soft references to softly reachable objects will have been cleared before it would ever throw an OutOfMemoryError.

Phantom References

Phantom references are the weakest of all reference types, calling get on them will always return null. An object is phantomly referenced after it has been finalized, but before its allocated memory has been reclaimed, As opposed to weak references which are enqueued before they’re finalized or GC’d Phantom references are rarely used.

So how are they useful? When you construct a phantom reference you must always pass in a ReferenceQueue. This indicates that you can use a phantom reference to see when your object is GC’d.

Hey, so if weak references are enqueued when they’re considered finalize but not yet GC’d we could create a new strong reference to the object in the finalizer block and prevent the object being GC’d. Yep, you can but you probably shouldn’t do this. To check for this case the GC cycle will happen at least twice for each object unless that object is reachable only by a phantom reference. This is why you can run out of heap even when your memory contains plenty of garbage. Phantom references can prevent this.

You can read more on my article Types of References in Java(Strong, Soft, Weak, Phantom).

참고URL : https://stackoverflow.com/questions/9809074/java-difference-between-strong-soft-weak-phantom-reference

반응형