preface

Use Java development, we don’t need to manage the life cycle of object, because the JVM will help us to recycle, but it is safe, obviously not, because the JVM heap area exists many not recycled object instance, then the possible memory leak, so we it is necessary for strong reference and a weak reference, soft references, Know something about virtual references.

Strong reference

What necessities do we have in our house? I feel like a bed, chest these things is essential, even if only 20 square meters room, we still need to, so strong reference can be seen as a bed, wardrobe, we in the development, will create many object instances, most of them are strong reference, strong references will not be the JVM recycle, even OutOfMemory happened not recycled, It will not be collected unless we set it to NULL.

public class StrongReference {
    public static void main(String[] args) {
        User user = new User("steak"); System.out.println(user); System.gc(); System.out.println(user); }}Copy the code
User(username=steak)
User(username=steak)
Copy the code

The user created above is a strong reference. We used system.gc () to reclaim the user manually. The user is not reclaimed, and we need to set user to null before the JVM will reclaim the user.

public class StrongReference {
    public static void main(String[] args) {
        User user = new User("steak");
        System.out.println(user);
        user = null; System.gc(); System.out.println(user); }}Copy the code
User(username=steak)
null
Copy the code

Soft references

Soft references can be understood as the discretionary in the home, but is based on the home is very sufficient space, if space is enough, then you won’t lose, if the space in the home, can be discarded, is just like some old table is not commonly used, the space of time in the home, can keep it, but the space is insufficient, can be lost it, in the JVM, If there is enough memory, soft references are not reclaimed, and if there is not enough memory, they are reclaimed.

public class SoftReferenceTest {
    public static void main(String[] args) {
        SoftReference<Object> softReference = new SoftReference<>(new User("steak")); System.out.println(softReference.get()); System.gc(); System.out.println(softReference.get()); }}Copy the code
User(username=steak)
User(username=steak)
Copy the code

The user was not reclaimed because there was enough space.

Soft reference application

Such as we need to read a lot of images to memory, in order to improve the query speed, if every time every time I read from the file server to read, so performance will have great influence, so it is stored in memory, but the store a lot of pictures in memory, may lead to memory overflow, so using soft reference to solve this problem, When the memory is insufficient, it will be recycled, when the memory is sufficient, it will not be recycled, then you can directly go back from the memory, greatly improving the speed of the query.

public class ImagesCache {
    private final Map<String, SoftReference<ImageInfo>> map = new HashMap<>();

    public void add(ImageInfo imageInfo){
        if(imageInfo ! =null){
            SoftReference<ImageInfo> softReferenceImage = newSoftReference<ImageInfo>(imageInfo); map.put(imageInfo.getUrl(),softReferenceImage); }}public ImageInfo get(String url){
        SoftReference<ImageInfo> img = map.get(url);
        if (img == null){
            System.out.println("image does not exist");
            return null;
        }
       returnimg.get(); }}Copy the code

As defined above, a Map is used to store images. Key is the IMAGE URL and value is the soft reference of the image object.

A weak reference

A weak reference, in contrast to a soft reference, does not wait until it runs out of memory to be collected, but is collected whenever the JVM does garbage collection.

public class WeakReferenceTest {
    public static void main(String[] args) {
        WeakReference<User> userWeakReference = new WeakReference<>(new User("steak")); System.out.println(userWeakReference.get()); System.gc(); System.out.println(userWeakReference.get()); }}Copy the code
User(username=steak)
null
Copy the code

When system.gc () was manually collected, we found that the user reference was reclaimed.

Note: It is important to note that if a strong reference is associated with a weak reference, the weak reference will not be reclaimed.

public class WeakReferenceTest {
    public static void main(String[] args) {
        WeakReference<User> userWeakReference = new WeakReference<>(new User("steak")); Object b = userWeakReference.get(); System.gc(); System.out.println(userWeakReference.get()); System.out.println(b); }}Copy the code
User(username=steak)
User(username=steak)
User(username=steak)
Copy the code

If a weak reference userWeakReference is assigned to Object B, then userWeakReference and B are associated, so the weak reference cannot be reclaimed by the JVM.

After we set b to NULL, it can be reclaimed

public class WeakReferenceTest {
    public static void main(String[] args) {
        WeakReference<User> userWeakReference = new WeakReference<>(new User("steak"));
        Object b = userWeakReference.get();
        System.out.println(userWeakReference.get());
        b = null; System.gc(); System.out.println(userWeakReference.get()); System.out.println(b); }}Copy the code
User(username=steak)
null
null
Copy the code

Phantom reference

Unlike other references, which can be reclaimed at any time, a virtual reference needs to be used in conjunction with the ReferenceQueue.

public class PhantomReferenceTest {
    public static void main(String[] args) {
        ReferenceQueue<Object> referenceQueue = new ReferenceQueue<>();
        PhantomReference<User> phantomReference = new PhantomReference<>(new User("123"),referenceQueue); System.out.println(phantomReference.get()); }}Copy the code
null
null
Copy the code

You can see from the output that the virtual reference was reclaimed.

conclusion

Weak references will be collected whenever the JVM garbage collects them, while virtual references will be collected whenever the JVM garbage collects them.