JVM notes (2) The life and death of objects and the four major references to java

For garbage collection, we must first determine whether an object is garbage, that is, whether the object is no longer used.

1. The life and death of the object

1.1 Reference counting method

Add a reference counter to the object. If it is referenced in a place, the counter is +1. When the corresponding reference is invalid, the counter is decremented by one; the counter is 0 and cannot be used again.

The principle is simple and the efficiency is high, but it cannot solve the circular reference problem.

The mainstream Java virtual machine does not use this method

public class _01Reference {
    public Object instance=null;

    private static final int _1MB=1024*1024;

    private byte[] bigSize=new byte[2*_1MB];
    /**
     * -XX:+PrintGC 输出GC日志
     * -XX:+PrintGCDetails 输出GC的详细日志
     * -XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
     * -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
     * -XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
     * -Xloggc:../logs/gc.log 日志文件的输出路径
     * @param args
     */
    public static void main(String[] args) {
        _01Reference r1=new _01Reference();
        _01Reference r2=new _01Reference();

        r1.instance=r2;
        r2.instance=r1;

        r1=null;
        r2=null;

        System.gc();
    }
}

Two objects refer to each other, but the virtual machine does not perform GC because the two objects refer to each other

1.2 Accessibility analysis

This algorithm is adopted by the memory management subsystem of the current mainstream commercial grammar and also adopted by the JVM.

The algorithm attempts to pass a series of ** "GC Roots" root objects as the starting node collection **, starting from these sections to search downwards according to the reference relationship, the path traversed by the search process is called "reference chain" There is no reference chain from the object to the GC Roots, indicating that this object cannot be used.

Simply put, all unreachable objects from the root node set are determined to be dead, and reachable objects are determined to be active.

Insert picture description here

As above: Although objects 5, 6, and 7 are related to each other, they are unreachable from GC Roots because they are determined to be recyclable objects.

Can be used as the object of GC Roots:

  1. Objects referenced in the stack ( local variable table in the stack frame )

  2. Objects referenced by class-like static properties in the method area

  3. Objects referenced by constants in the method area (such as references in string constant pools)

  4. Objects referenced by JNI (Native method) in the local method stack

  5. Internal reference of virtual machine (Class object corresponding to basic data type, resident exception object (NPE, OOM), system class loader)

  6. All objects held by the synchronize keyword

1.3 Reference

Java references are divided into strong references, soft references, weak references and virtual references

Overall structure

Located under the java.lang.ref package:

Insert picture description here

Strong reference

Object obj=new Object()A reference relationship like this is called a strong reference

For strongly referenced objects, even if OOM appears, the object will not be recycled

Object obj1=new Object();
Object obj2=obj1;
obj1=null;
System.gc();
Sytem.out.printIn(obj2)

As above code, obj2 will not be recycled

Soft reference

lie injava.lang.ref.SoftReference

Some useful, but not necessary objects. Before the system will run out of memory, these objects will be listed as the second recycling object. If there is not enough memory for this recycling, OOM will be thrown.

If the memory is enough, it will not be recycled

Memory is not enough to recover ----> recovered enough -----> OOM

Used in memory sensitive places, such as cache

 /**
     * 内存够用时 软引用对象不被回收
     */
    public static void memoryEnough(){
        Object obj1=new Object();
        SoftReference<Object>softReference=new SoftReference<>(obj1);
        System.out.println(obj1);
        System.out.println(softReference.get());

        obj1=null;
        System.gc();
        System.out.println(obj1);//null
        System.out.println(softReference.get());//有对象
    }

    /**
     * 内存不够用,会回收软引用对象
     * -Xms10M -Xmx10M -XX:+PrintGCDetails
     */
    public static void notEnough(){
        Object obj1=new Object();
        SoftReference<Object>softReference=new SoftReference<>(obj1);
        System.out.println(obj1);
        System.out.println(softReference.get());

        obj1=null;
        try {
            byte[]bytes=new byte[20*1024*1024];

        }finally {
            System.out.println(obj1);//null
            System.out.println(softReference.get());//null
        }

    }

Soft reference use

The cache will be very commonly used. We use soft references to save cached data. When OOM occurs, the system will retrieve the cached data of these soft references.

Weak reference

lie injava.lang.ref.WeakReference

Non-essential objects, regardless of whether the memory is enough, will be recycled by GC

 public static void main(String[] args) {
        Object o1=new Object();
        WeakReference<Object>weakReference=new WeakReference<>(o1);
        System.out.println(o1);//java.lang.Object@677327b6
        System.out.println(weakReference.get());//java.lang.Object@677327b6

        o1=null;
        System.gc();
        System.out.println(o1);//null
        System.out.println(weakReference.get());//null
    }

If the above memory is enough, GC will still be recycled, and if there is not enough memory, it will be recycled. I will not demonstrate it here.

WeakHashMap

private static void weakHashMap() {
        WeakHashMap<Integer,Object> map=new WeakHashMap<>();
        Integer key=new Integer(1);
        Object value="value";
        map.put(key,value);
        System.out.println(map);//{1=value}
        key=null;
        System.gc();
        System.out.println(map);//{}
    }
private static void hashMap(){
        HashMap<Integer,String>map=new HashMap<>();
        Integer key=new Integer(1);
        String value="wml";
        map.put(key,value);
        System.out.println(map);//{1=wml}
        key=null;
        System.gc();
        System.out.println(map);//{1=wml}

    }

Virtual reference

lie injava.lang.ref.PhantomReference

Also called "ghost reference" or "phantom reference", the weakest reference relationship

It is not possible to obtain an object instance through virtual reference get ().

It is only used to receive a system notification when the object is recycled, or to add further processing, which must be used with the reference queue.

 public static void main(String[] args) throws InterruptedException {
        Object o1=new Object();
        ReferenceQueue<Object>queue=new ReferenceQueue<>();
        PhantomReference<Object> phantomReference=new PhantomReference<>(o1, queue);

        System.out.println(o1);//java.lang.Object@677327b6
        System.out.println(phantomReference.get());//null
        System.out.println("引用队列:"+queue.poll());//null
        System.out.println("=============发生GC后========");

        o1=null;
        System.gc();
        System.out.println(o1);//null
        System.out.println(phantomReference.get());//null
        System.out.println("引用队列:"+queue.poll());//java.lang.ref.WeakReference@14ae5a5

    }

1.4 Subject's self-rescue

The death of an object requires at least two marks.

The first time: when there is no reference link connected to GC Roots after reachability analysis

The second time: whether the object should implement the finalize () method

If the object overrides the finalize method and re-establishes a connection with any object in the reference chain in this method , it means that the object has successfully saved itself and will be removed from the collected collection.

package com.wml.jvm.gc;

/**
 * 1.对象可以在被GB时进行逃逸
 * 2.这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次
 * @author MaoLin Wang
 * @date 2020/3/1216:39
 */
public class _02FinalizeEscapeGC {
    public static Object obj1 =null;

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalize方法执行");
        obj1 =this;
    }

    private  static void gc(){
        System.gc();
        System.out.println("开始垃圾回收");
    }
    public static void main(String[] args) throws InterruptedException {
        obj1 =new _02FinalizeEscapeGC();

        //对象第一次进行自我拯救(逃避GC)
        obj1 =null;
        gc();
        //因为finalize方法优先级很低,所有等待一下
        Thread.sleep(500);
        if (obj1 !=null){
            System.out.println("first->对象仍然存活");
        }else {
            System.out.println("first->对象已死亡");
        }

        //对象第二次进行自我拯救(逃避GC),但因为finalize已经被调用了一次,因此无法逃逸成功
        obj1 =null;
        System.gc();
        //因为finalize方法优先级很低,所有等待一下
        Thread.sleep(500);
        if (obj1 !=null){
            System.out.println("Second->对象仍然存活");
        }else {
            System.out.println("Second->对象已死亡");
        }

    }
}

result:

调用了finalize方法
开始垃圾回收
first->对象仍然存活
Second->对象已死亡

However, the official has not recommended this approach because of the high operating cost and high uncertainty.

1.5 Recovery of the method area

Recycling target:

  1. Obsolete constant

    A constant is recycled when it is not referenced anywhere else. Symbolic references to other classes, methods, and fields in the constant pool

  2. Types that are no longer used

    The conditions under which types are allowed to be recovered are as follows:

    a. All instances of this class are recycled

    b. The class loader that loaded the class has been recycled

    c. The java.class.Class object corresponding to this class is not referenced anywhere, and the methods of this class cannot be accessed by reflection anywhere

    In a large number of bytecode frameworks such as reflection, dynamic proxy, and CGLib, the virtual machine needs to be able to perform type unloading to reduce the pressure on the method area.

======================================================================

Other related notes:

JVM notes (1) java memory area and memory overflow and object creation, layout and positioning

JVM notes (3) garbage collection algorithm and HotSpot algorithm implementation (security point, memory set and card table, write barrier, three-color mark, etc.)

JVM notes "Four" seven common garbage collectors

JVM notes (five) class loading mechanism, class loader and parent delegation mechanism

================================================================

Reference:
"In-depth understanding of the third edition of java virtual machine"

Published 75 original articles · won praise 13 · views 8369

Guess you like

Origin blog.csdn.net/weixin_43696529/article/details/104884444