zoukankan      html  css  js  c++  java
  • 说说WeakReference弱引用

    WeakReference弱引用概述

    http://www.cnblogs.com/xrq730/p/4836700.html,关于Java的四种引用状态具体请参看此文

    Java里一个对象obj被创建时,被放在堆里。当GC运行的时候,发现没有任何引用指向obj,那么就会回收obj对象的堆内存空间。

    但是现实的情况时,写代码的时候,往往通过把所有指向某个对象的引用置空来保证这个对象在下次GC运行的时候被回收:

    Object obj = new Object();

    obj = null;

    这种方式说可以吧,也不是不可以,但是对于程序员来说,这是一件繁琐而且未被自动回收理念的。手动置空不应该需要程序员来做的,因为对于一个简单的对象而言,当调用它的方法执行完毕,引用会自动从栈中弹出,这样下一次GC的时候就会自动回收这块内存了。

    但 是有例外。比如说缓存,由于缓存对象是程序需要的,那么只要程序正在运行,缓存中的引用是不会被GC的,随着缓存中的引用越来越多,GC无法回收的对象也 越来越多,无法被自动回收。当这些对象需要被回收时,回收这些对象的任务只有交给程序员了,然而这却违背了GC的本质----自动回收。

    所以Java中引入了弱引用WeakReference。

    WeakReference弱引用示例

    下面演示一下WeakReference简单的使用,首先定义一个实体类:

    复制代码
    public class Car
    {
        private double     price;
        private String    color;
        
        public Car(double price, String color)
        {
            this.price = price;
            this.color = color;
        }
        
        public double getPrice()
        {
            return price;
        }
    
        public String getColor()
        {
            return color;
        }
    
        public String toString()
        {
            return "This car is a " + this.color + " car, costs $" + price;
        }
    }
    复制代码

    一般使用WeakReference的时候都会定义一个类继承自WeakReference,在这个类中再定义一些别的属性,这里就不定义别的属性了:

    复制代码
    public class WeakReferenceCar extends WeakReference<Car>
    {
        public WeakReferenceCar(Car car)
        {
            super(car);
        }
    }
    public class WeakReferenceCar extends WeakReference<Car>
    {
        public WeakReferenceCar(Car car)
        {
            super(car);
        }
    }
    复制代码

    main函数调用一下,当然为了更清楚地看到GC的效果,设置虚拟机参数"-XX:+PrintGCDetails":

    复制代码
    public static void main(String[] args)
        {
            Car car = new Car(2000.0, "red");
            WeakReferenceCar wrc = new WeakReferenceCar(car);
            wrc.setStr("111");
            int i = 0;
            while (true)
            {
                if (wrc.get() != null)
                {
                    i++;
                    System.out.println("WeakReferenceCar's Car is alive for " + i + ", loop - " + wrc);
                }
                else
                {
                    System.out.println("WeakReferenceCar's Car has bean collected");
                    break;
                }
            }
        }
    复制代码

    看一下运行结果:

    复制代码
    WeakReferenceCar's Car is alive for 22880, loop - com.xrq.test14.WeakReferenceCar@5d888759
    WeakReferenceCar's Car is alive for 22881, loop - com.xrq.test14.WeakReferenceCar@5d888759
    WeakReferenceCar's Car is alive for 22882, loop - com.xrq.test14.WeakReferenceCar@5d888759
    WeakReferenceCar's Car is alive for 22883, loop - com.xrq.test14.WeakReferenceCar@5d888759
    WeakReferenceCar's Car is alive for 22884, loop - com.xrq.test14.WeakReferenceCar@5d888759
    [GC [PSYoungGen: 16400K->256K(18688K)] 16400K->256K(61440K), 0.0002863 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
    WeakReferenceCar's Car is alive for 22885, loop - com.xrq.test14.WeakReferenceCar@5d888759
    WeakReferenceCar's Car has bean collected
    Heap
     PSYoungGen      total 18688K, used 899K [0x0000000034180000, 0x0000000035650000, 0x0000000048f80000)
      eden space 16064K, 4% used [0x0000000034180000,0x0000000034220c30,0x0000000035130000)
      from space 2624K, 9% used [0x00000000353c0000,0x0000000035400000,0x0000000035650000)
      to   space 2624K, 0% used [0x0000000035130000,0x0000000035130000,0x00000000353c0000)
     PSOldGen        total 42752K, used 0K [0x000000000a580000, 0x000000000cf40000, 0x0000000034180000)
      object space 42752K, 0% used [0x000000000a580000,0x000000000a580000,0x000000000cf40000)
     PSPermGen       total 21248K, used 3016K [0x0000000005180000, 0x0000000006640000, 0x000000000a580000)
      object space 21248K, 14% used [0x0000000005180000,0x0000000005472318,0x0000000006640000)
    复制代码

    看到22884次循环之后,WeakReferenceCar关联的对象Car被回收掉了,注意是弱引用关联的对象car被回收,而不是弱引用本身wrc被回收。

    其他

    1、除了弱引用,还有软引用。SoftReference(软引用)和WeakReference的区别在于,假如下次GC的时候,发现内存没有溢出,则不会回收SoftReference关联的对象,但是对于WeakReference,在下一次GC的时候,一定会回收,无论内存是否满。像缓存,其实最适合的个人认为应该是SoftReference,因为缓存里面的数据是运行时会用到的,能不回收就尽量不要去回收它们,而等到内存实在不够的时候再去回收

    2、WeakReference的父类Reference中有一个变量queue,是ReferenceQueue类型的。WeakReference中的构造函数中有一个两个参数的构造函数,其中第二个参数就是这个ReferenceQueue,表示在WeakReference指向的对象被回收之后,可以利用ReferenceQueue来保存被回收的对象

  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/szlbm/p/5504645.html
Copyright © 2011-2022 走看看