Deep discussion on Java strong reference, soft reference, weak reference and virtual reference

Deep discussion on strong reference, soft reference, weak reference and virtual reference

Reference types are not often concerned and rarely noticed in daily development, so many people ignore their existence. In fact, reference types play a very important role in the Java system. In order to have a deeper understanding of the Java system, it is very necessary to understand and master the usage of these references.

Before we start, let's serve two appetizers.

Why recycle

Each object in a java program will occupy certain computer resources. The most common is that each object will apply for a certain memory space in the heap space. However, in addition to memory, objects also occupy other resources, such as file handles, ports, sockets and so on. When you create an object, you must ensure that it will release the resources it occupies when it is destroyed. Otherwise, the program will end its mission in oom.

In Java, there is no need for programmers to manage the allocation and release of memory. Java has an artifact for automatic memory management - garbage collector, which will automatically recycle objects that are no longer used.

In Java, you don't need to explicitly release memory like C or C + +, you don't need to understand the details of recycling, and you don't need to worry about memory corruption caused by releasing the same object twice. All this, the garbage collector will help you deal with it automatically. You just need to ensure that all references to objects that are no longer used have been released, otherwise your program will end up in a memory leak as in C + +.

Although the garbage collector does make memory management in Java much easier than that in C and C + +, you can't be completely indifferent to memory. If you don't know under what conditions the JVM will recycle objects, you may accidentally leave a memory leak bug in the code.

Therefore, paying attention to the recycling timing of objects and understanding the garbage collection mechanism in the JVM can not only improve the sensitivity to this problem, but also locate the problem faster in case of memory leakage. For more details about garbage collection, please refer to this article.

Why do I need a reference type

Reference types are types that work closely with the JVM. Some reference types even allow their reference objects to be released by the JVM when they are still needed in the program.

So why do you need these reference types?

In Java, the garbage collector thread has been working silently, but you can't control it in the code. The garbage collector cannot be asked to recycle some objects at a precise point in time.

With these reference types, you can increase the granularity control of garbage collection to a certain extent, so that the garbage collector can recycle the objects that can be recycled at a more appropriate time, not just the objects that are no longer used.

These reference types have their own characteristics and application scenarios. A clear understanding and mastery of their usage can help you write more robust code.

explain

In versions prior to JDK 1.2, if an object is not referenced by any variables, the program can no longer use the object. In other words, the program can use an object only when it is in the reachable state. The garbage collector will collect the object only when it is not referenced by any other object. The object has only two states: referenced and unreferenced. This method cannot describe some objects that are "tasteless to eat and regrettable to discard".

Most of the time, we want to have such objects: when the memory space is enough, we can save them in memory without recycling; Allow the JVM to reclaim these objects when memory space becomes tight. Most caches fit this scenario.

Since JDK version 1.2, Java has expanded the concept of reference, and the reference of objects is divided into four levels, so that program developers can more flexibly control the life cycle of objects and better control when created objects are released and recycled.

The four levels from high to low are: strong reference, soft reference, weak reference and virtual reference.

Strength rollover

Welcome to the large rollover scene. Next, we will demonstrate a wave of rollover examples caused by too many strong references.

If you need to save some objects throughout the program (because their initialization takes time and resources), you may use static collection objects to store them and use them everywhere in your code.

public static Map<K,V> storedObjs = new HashMap<>();

However, this prevents the garbage collector from collecting and destroying objects in the collection. This may lead to oom. For example:

public class OOMTest {
    public static List<Integer> cachedObjs = new ArrayList<>();
 
    public static void main(String[] args) {
        for (int i = 0; i < 100_000_000; i++) {
            cachedObjs.add(i);
        }
    }
}

The output is as follows:

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

This is in line with the expected rollover. But you might say, who would be so boring to create so many variables.

Well, it is, but don't forget that a program may run for a long time, months or even years (if your code and company are robust enough), and this may happen if you constantly create variables without cleaning them (use HashMap as a cache as above).

Content arrangement

The following article will introduce these four references from the following aspects:

If you just want to have a brief understanding of these references, you can finish the brief introduction. If you want to have more in-depth research, you can continue to refer to the source code analysis section.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>