Deep understanding of WeakHashmap

WeakHashmap

(1) Check the API documentation. The main points of WeakHashmap are as follows:

1. A hash-based Map implemented with weak keys. In a WeakHashMap, when a key is no longer in normal use , its entry is automatically removed. More precisely, the existence of a map for a given key does not prevent the garbage collector from discarding that key, which makes the key terminable, terminated, and then recycled. When a key is discarded, its entry is effectively removed from the map

2. The behavior of the WeakHashMap class depends in part on the actions of the garbage collector. Because the garbage collector may discard keys at any time, the WeakHashMap is like an unknown thread whose entries are quietly removed. In particular, even if the WeakHashMap instance is synchronized and no assignment methods are called, the size method may return a smaller value after a period of time, for the isEmpty method, return false, then return true, for a given key, the containsKey method Returns true then returns false, for a given key, the get method returns a value, but then returns null, for keys that previously appeared in the map, the put method returns null, and the remove method returns false, for keys set, value collection, and The check performed by the entry set produces fewer and fewer elements.

3. Each key object in the WeakHashMap is indirectly stored as a weak reference referent. Therefore, a key will only be automatically removed after the garbage collector cleans up weak references to it, whether inside or outside the map.

(2) Four categories of reference objects:

The Api picture is as follows:

1. Strong Reference

2. Weak Reference

3.  Soft Reference

4. Phantom Reference

(3) In-depth understanding

So far, we have a basic concept for WeakHashMap, but it is still vague. Find an English document and summarize the main points as follows (if the translation is wrong, please point out, thank you):

1. Strong citations

Strong references are ordinary Java references, code:

 
 
  1. StringBuffer buffer = new StringBuffer(); 

This code creates a StringBuffer object and stores a strong reference to this object in the variable buffer. Strong references are called "strong" because of the way they interact with the garbage collector. Specifically, if an object is linked by a strong reference (strongly reachable), then it is not subject to garbage collection. When you're using an object and don't want it to be destroyed during garbage collection, strong references are usually just what you want.

2. When strong references are too strong

Suppose you want to use a final class Widget, but for some reason, you cannot extend this class or add some new functionality to this class in other ways. If you need to track the serial number of different objects of this class. Then you can put these objects into HashMap to get different value values, so that you can track these objects through different value values. Code: 

 
 
  1. serialNumberMap.put(widget, widgetSerialNumber); 

But strong references to widgets can create some problems. When we don't need the serial number of a Widget, we need to remove the Entry corresponding to the Widget from the HashMap. Otherwise we could face a memory leak (if we didn't remove the Widget when it should have been removed), or we would have lost the serial number somehow (if we were using the Widget and removed it). If these problems are similar, then these problems are problems faced by developers of non-garbage-collected languages. Java developers don't need to worry about this.

W: If an object has a strong reference, it's like an essential household item, and the garbage collector will never recycle it. When the memory space is insufficient, the Java virtual machine would rather throw an OutOfMemoryError error to cause the program to terminate abnormally, rather than reclaiming objects with strong references at will to solve the problem of insufficient memory.

Another common problem with strong references is image caching. Ordinary strong references will keep the Image in memory. In some cases, we don't need some images to remain in memory, we need to remove these images from memory, at this time, we will play the role of garbage collection period to decide which photos are removed. Cause these removed images to be destroyed by the garbage collector. Next time, you're forced to play the role of the garbage collector again, manually deciding which images are collected.

Note: I think it is also possible to track objects by their hashCode. The examples given by the author here are only to illustrate the Strong Reference.

3. Weak references

Simply put, a weak reference is not enough to force the object to which it is attached to be kept in memory. Weak references can leverage the reachability level of an object in the garbage collector. Code:

 
 
  1. WeakReference<Widget> weakWidget = new WeakReference<Widget>(widget); 

You can use the weakWidget.get() method to get the actual strong reference object. But after that, it is possible to suddenly return a null value (if there are no other strong references to the Widget), because the weak reference is reclaimed. The packaged Widgets are also recycled.

The easiest way to solve the problem of Widget serial number is to use WeakHashmap. Its key value is a weak reference. If a WeakHashmap's key becomes garbage, its value to the application is also automatically removed.

W: The garbage collection period does not always find a weak reference the first time, but it takes a few times to find it.

4. Reference Queue

Once the weak reference returns a null value, the object it points to (ie Widget) becomes garbage, and the weak reference object (ie weakWidget) is useless. This usually means doing some sort of cleanup. For example, WeakHashmap will remove some dead (dread) entries to avoid holding too many dead weak references.

ReferenceQuene can easily track down these dead weak references. It can be said that ReferenceQuene is passed into the constructor of WeakHashmap, so that once the object pointed to by this weak reference becomes garbage, this weak reference will be added to ReferenceQuene.

As shown below:

5. Soft references

A soft reference is basically the same as a weak reference, except for the urgency of throwing the object it points to. An object is weakly reachable (or the strong reference to the object is a weak reference object - that is, a weak reference encapsulation of a strong reference), the object will be discarded in a garbage collection cycle. However, weakly referenced objects are retained for a period of time before being discarded.

The implementation of soft references is not any different from weak references. However, in plentiful supply, soft reachable objects will remain in memory for as long as possible. This gives them an excellent base of existence in memory (i.e. a base that lasts as long as possible). Because you're letting the garbage collector worry about two things, the reachability of this object, and how much the garbage collection period wants the memory those objects are consuming.

6. Phantom reference

Phantom references are different from weak and soft references. Its control over the object it points to is so tenuous that it cannot acquire the object. The get() method usually returns a null value. Its only purpose is to keep track of dead objects queued in the ReferenceQuene.

The difference between a phantom reference and a weak reference is the way it is enqueued into the ReferenceQuene. When the object of the weak reference becomes reachable, the weak reference is queued into the ReferenceQuene. This enqueue happens before finalize and garbage collection actually happens. In theory, an object that becomes garbage can be resurrected via an unorthodox finilize() method, but weak references are still dead. Phantom references are only enqueued when the object is physically removed from memory. This prevents us from recovering dying objects.

W: Finalization refers to a more general concept than garbage collection, which can reclaim any resources occupied by objects, such as file descriptors and graphics contexts.

Phantom references have two benefits:

A: It is the only way to determine when an object is removed from memory. Normally, this is not very useful. But sooner or later (come in handy) the case of manually processing large images comes into play: if you decide that an image needs to be garbage collected, then you should wait for the image to be garbage collected before you try to load the next photo. This makes dreaded memory overflows less likely.

B: Unreal references can avoid the fundamental problem of finilize. The finilize() method can revive a garbage object by associating it with a strong reference. The problem is overwritingBefore the object of the finilize() method becomes garbage, in order to collect it, the garbage collection period needs to perform two separate cycles. The first round of the loop determines that an object is garbage, then it meets the conditions for finalizing the finalize. During the finilize process, this object may be "resurrected". Before the object is actually removed, the garbage collection period has to run again. Because finilization is not called in real time, multiple loops of gc may occur during the process of termination. This caused some latency lag when the garbage objects were actually cleaned up. This will cause a large amount of garbage in the Heap to cause a memory overflow.

The above cannot happen with a phantom reference, when a phantom reference is enqueued, it has actually been removed from memory. Phantom memory cannot "reanimate" objects. When this object is found unreal reachable, in the first round of the loop, it is reclaimed.

Arguably, the finilize() method is never used in the first case, but Unreal References provides a safer and more efficient mechanism to use and exclude the finilize method, making garbage collection easier. But because there are so many things to implement, I usually don't use finilize.

The relevant content in the W:Object class is as follows:

The relevant content in the document is as follows:

(4) Original address and other translations

Original address: http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

Other translation addresses: http://blog.csdn.net/fancyerii/article/details/5610360

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326801899&siteId=291194637