smile908

导航

java弱引用之WeakReference

1:什么是java的弱引用呢?

在Java里, 当一个对象被创建时, 它被放在内存堆里. 当GC运行的时候, 如果发现没有任何引用指向该对象, 该对象就会被回收以腾出内存空间. 或者换句话说, 一个对象被回收, 必须满足两个条件:

1:没有任何引用指向它

2:GC被运行。

Java对于简单的情况, 手动置空是不需要程序员来做的, 因为在java中, 对于简单对象, 当调用它的方法执行完毕后, 指向它的引用会被GC回收,

实际中我们写代码,往往是通过把所有指向某个对象的referece置null实现,如:

Person person=new Person("xlc",23,1);

person=null;
System.gc();

很明显,手动置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实体类:

public class Person {
String name;
int age;
int sex;

public Person() {
}

public Person(String name, int age, int sex) {
this.name = name;
this.age = age;
this.sex = sex;
}

@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", 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 int getSex() {
return sex;
}

public void setSex(int sex) {
this.sex = sex;
}
}
测试类:
public class fft {
public static void main(String[] args) {
int i=0;
Person person=new Person("xlc",23,1);
WeakReference<Person> weakReference =new WeakReference<Person>(person);
while (true) {
if (weakReference.get() != null) {
i++;
System.out.println("weakReference已经运行了" + i + "次");
} else {
System.out.println("程序退出!!");
break;
}
}
}
}

运行结果:

weakReference已经运行了231351次
weakReference已经运行了231352次
weakReference已经运行了231353次
weakReference已经运行了231354次
weakReference已经运行了231355次
程序退出!!

程序在运行数万次退出,并且每次的运行结果都不一样,由此说明

可以看到,在while循环执行数万次后,person被回收了。

多次测试运行程序,发现p回收时循环执行的次数是不确定的,这个很容易理解:因为这是由GC运行的不确定性所确定的。

 

第二次测试,我们将person对象置空,并主动调用gc进行一个内存的回收

import java.lang.ref.WeakReference;

public class fft {
public static void main(String[] args) {
int i=0;
Person person=new Person("xlc",23,1);
WeakReference<Person> weakReference =new WeakReference<Person>(person);
while (true) {
if (weakReference.get() != null) {
i++;
System.out.println("weakReference已经运行了" + i + "次");
if(i==100){
person=null;
System.gc();
}
} else {
System.out.println("程序退出!!");
break;
}
}
}
}

 

 这次,程序运行了100次后,person被手动置为空对象,被gc进行了一个回收。

至此,我们可以看到关于弱引用的几个特点。

1.Java中当一个对象仅被一个弱引用引用时,如果GC运行, 那么这个对象就会被回收。

2.弱引用的一个特点是它何时被回收是不可确定的;

 

posted on 2022-10-11 09:19  smile908  阅读(99)  评论(0编辑  收藏  举报