java虚拟机(3)-引用

判断对象的存活

引用计数法:快,方便,实现简单;缺点:对象相互应用,很难判断对象是否回收

可达性分析

判断对象是否存活的。这个算法的基本思路是通过系列的称为“GC Roots”的对象作为起始点,从这些几点开始向下搜索,搜索所走过的路径称为引用链接(reference Chain),当一个对象GC roots没有任何应用链相连是,则证明此对象是不可用的。

作为GC Roots的对象包括下面几种:

  • 虚拟机栈(栈帧中的本地变量表)中引用对象。
  • 方法区中的类静态属性引用的对象。
  • 方法区中常量引用对象。
  • 本地方法栈中JNI(即一般说的Native方法)引用的对象
image.png

引用

强引用

  • 一般的Object obj = new Object(); 就属于强引用

软引用 SoftReference

  • 一些有用但是并非必需,用软引用关联的对象,系统将要发生OMM(内存溢出)之前,这些对象就会被回收。
public static class User{
        
        public int id = 0;
        public String name = "";    
        
        public User(int id,String name) {
            this.id = id;
            this.name=name;
        }
    
    }
    


    public static void main(String[] args) {
        
        User user = new User(1, "小明");
        SoftReference userSoft = new SoftReference(user);
        user = null;
        
        System.out.println(userSoft.get());
        System.gc();
        System.out.println("GC完成后");
        System.out.println(userSoft.get());
        
        List list = new  LinkedList();
        
        try {
            for (int i = 0; i < 10000; i++) {
            System.out.println("**********"+userSoft.get());
            list.add(new Byte[1024*1024*1]);
            }
            
        } catch (Throwable e) {
            System.out.println("Throwable***********"+userSoft.get());
        }
        
        
    }

运行结果:

[GC (System.gc())  893K->632K(9728K), 0.0013160 secs]
[Full GC (System.gc())  632K->569K(9728K), 0.0054084 secs]
GC完成后
com.enjoy.cap1.StackAlloc$User@7852e922
**********com.enjoy.cap1.StackAlloc$User@7852e922
**********com.enjoy.cap1.StackAlloc$User@7852e922
[GC (Allocation Failure)  4670K->4825K(9728K), 0.0002478 secs]
[GC (Allocation Failure)  4825K->4761K(9728K), 0.0003084 secs]
[Full GC (Allocation Failure)  4761K->4665K(9728K), 0.0064745 secs]
[GC (Allocation Failure)  4665K->4665K(9728K), 0.0004925 secs]
[Full GC (Allocation Failure)  4665K->4652K(9728K), 0.0067316 secs]
Throwable***********null

弱引用 WeakReference

一些有用(程度比软引用更低)但是并非必需,用弱引用相关的对象,只能生存到下一次垃圾回收之前,GC发生时,不管内存够不够,都会被回收

public static class User{
        
        public int id = 0;
        public String name = "";    
        
        public User(int id,String name) {
            this.id = id;
            this.name=name;
        }
    
    }
    


    public static void main(String[] args) {
        
        User user = new User(1, "小明");
        WeakReference userSoft = new WeakReference(user);
        user = null;
        
        System.out.println(userSoft.get());
        System.gc();
        System.out.println("GC完成后");
        System.out.println(userSoft.get());
        
    }

运行结果:

[GC (System.gc())  892K->600K(9728K), 0.0006343 secs]
[Full GC (System.gc())  600K->569K(9728K), 0.0039438 secs]
GC完成后
null

虚应用 PhantomReference

幽灵引用,最弱,被垃圾会后的时候收到一个通知

: 软引用SoftReference和弱引用WeakReference,可以用在内存资源紧张的情况下以及创建不是很重的数据缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。 例如:一个程序用来处理用户提供的图片。如果将所有图片读入内存,这样虽然可以很快的打开图片,但内存空间使用巨大,一些使用较少的图片浪费内存空,需要手动冲内存中移除,如果每次打开图片都是从磁盘文件中读取到内存中再显示出来,虽然内存占用较少,但一些经常使用的图片每次打开都要访问磁盘,代价巨大。这个是偶就是可以用软引用构建对象

你可能感兴趣的:(java虚拟机(3)-引用)