在java里, 当一个对象被创建时, 它被放在内存堆里. 当gc运行的时候, 如果发现没有任何引用指向该对象, 该对象就会被回收以腾出内存空间。
或者换句话说, 一个对象被回收, 必须满足两个条件:
1)没有任何引用指向它 (推荐学习:java课程)
2)gc被运行。
java对于简单的情况, 手动置空是不需要程序员来做的, 因为在java中, 对于简单对象, 当调用它的方法执行完毕后, 指向它的引用会被gc回收,
实际中我们写代码,往往是通过把所有指向某个对象的referece置null实现,如:
person p = new person("张三",18,"男");//强引用...p=null;//不再使用的时候置null
很明显,手动置null对象对于程序员来说, 是一件繁琐且违背自动回收机制的。
java对于简单的情况, 如方法中的产生的局部对象,是不需要程序员来手动置空, 当调用它的方法执行完毕后, 指向它的引用会被gc回收。
而复杂一点的情况,比如使用cache,因为cache的对象正是程序运行需要的,那么只要程序正在运行, cache中的引用就不会被gc,那么随着cache中的引用越来越多, gc无法回收的对象也越来越多,无法被自动回收,此时就必须有开发者来进行处理回收,显然也违背了java自动回收机制。
对此,java中引入了弱引用(weakreference)。
当一个对象仅仅被weak reference指向, 而没有任何其他strong reference指向的时候, 如果gc运行, 那么这个对象就会被回收。如果存在强引用同时与之关联,则进行垃圾回收时也不会回收该对象。
weakreference的语法:
weakreference<t> weakreference = new weakreference<t>(referent);
当要获得weak reference引用的对象时, 首先需要判断它是否已经被回收:
weakreference.get();
如果此方法为空, 那么说明weakreference指向的对象已经被回收了。
下面一个weakreference的栗子:
person类:
package com.yx.test.model; /** * person * * @author yx * @date 2019/11/26 16:28 */public class person { private string name; private int age; private string sex; public person() { } public person(string name, int age, string sex) { this.name = name; this.age = age; this.sex = sex; } public string getname() { return name; } public void setname(string name) { this.name = name; } public int getage() { return age; } public void setage(int age) { this.age = age; } public string getsex() { return sex; } public void setsex(string sex) { this.sex = sex; }}
测试类testweakreference:
package com.yx.test.reference; import com.yx.test.model.person; import java.lang.ref.weakreference; /** * testweakreference * * @author yx * @date 2019/11/26 16:30 */public class testweakreference { public static void main(string[] args) { person p = new person("张三",18,"男"); weakreference<person> weakperson = new weakreference<person>(p); int i=0; while(true){ if(weakperson.get()!=null){ i++; system.out.println("object is alive for "+i+" loops - "+weakperson); }else{ system.out.println("object has been collected."); break; } } }}
运行结果:
p is alive for 1 loops - java.lang.ref.weakreference@330bedb4...p is alive for 62331 loops - java.lang.ref.weakreference@330bedb4p is alive for 62332 loops - java.lang.ref.weakreference@330bedb4p has been collected.
可以看到,在while循环执行数万次后,p被回收了。
多次测试运行程序,发现p回收时循环执行的次数是不确定的,这个很容易理解:因为这是由gc运行的不确定性所确定的。
小结:
1.java中当一个对象仅被一个弱引用引用时,如果gc运行, 那么这个对象就会被回收。
2.弱引用的一个特点是它何时被回收是不可确定的;
以上就是java弱引用的理解与使用的详细内容。