您的位置:首页 > 职场人生

准备Java面试之——Java SE基础知识解答(二)

2017-09-18 07:50 639 查看
(5) Java的四种引用,强弱软虚,用到的场景。

《Thinking in Java》第四版中第518页讲解了这部分内容。引用如下:

java.lang.ref包含了一组类,这些类为垃圾回收提供了更大的灵活性,当存在可能会耗尽内存的大对象时,这些类就会显得特别有用。

在java.lang.ref包里面,有三个类SoftReference, WeakReference, PhantomReference继承自Reference类,他们从强到弱排列,代表着不同级别的“可获得性”。SoftReference可以用以实现内存敏感的告诉缓存;WeakReference是为实现“规范映射”而设计的,并不妨碍垃圾回收;PhantomReference用以调度回收前的清理工作,它比Java终止机制更灵活。

以下是摘自《Thinking in Java》的测试代码

package test;

import java.lang.ref.*;
import java.util.*;

class VeryBig{
private static final int SIZE = 10000;
private long[] la = new long[SIZE];
private String ident;
public VeryBig(String id){
ident = id;
}
public String toString(){
return ident;
}
protected void finalize(){
System.out.println("finalizing: " + ident);
}

}
public class References {
private static ReferenceQueue<VeryBig> rq = new ReferenceQueue<VeryBig>();
public static void checkQueue(){
Reference<? extends VeryBig> inq= rq.poll();
if(inq != null){
System.out.println("In quene: " + inq.get());
}
}

public static void main(String args[]){
int size = 2;
if(args.length > 0){
size = new Integer(args[0]);
}
LinkedList<SoftReference<VeryBig>> sa = new LinkedList<SoftReference<VeryBig>>();
for(int i = 0; i < size; i++){
sa.add(new SoftReference<VeryBig>(new VeryBig("soft" + i),rq));
System.out.println("Just Created: " + sa.getLast());
checkQueue();
}

LinkedList<WeakReference<VeryBig>> wa = new LinkedList<WeakReference<VeryBig>>();
for(int i = 0; i < size; i++){
wa.add(new WeakReference<VeryBig>(new VeryBig("weak" + i),rq));
System.out.println("Just Created: " + wa.getLast());
checkQueue();
}
SoftReference<VeryBig> s = new SoftReference<VeryBig>(new VeryBig("soft"));
WeakReference<VeryBig> w = new WeakReference<VeryBig>(new VeryBig("weak"));
System.gc();

LinkedList<PhantomReference<VeryBig>> qa = new LinkedList<PhantomReference<VeryBig>>();
for(int i = 0; i < size; i++){
qa.add(new PhantomReference<VeryBig>(new VeryBig("Phantom" + i),rq));
System.out.println("Just Created: " + qa.getLast());
checkQueue();
}
}

}


运行结果为:

Just Created: java.lang.ref.SoftReference@7852e922

Just Created: java.lang.ref.SoftReference@4e25154f

Just Created: java.lang.ref.WeakReference@70dea4e

Just Created: java.lang.ref.WeakReference@5c647e05

finalizing: weak

finalizing: weak1

finalizing: weak0

Just Created: java.lang.ref.PhantomReference@33909752

In quene: null

Just Created: java.lang.ref.PhantomReference@55f96302

In quene: null

由此可见softReference没有被回收,但是weakReference被回收掉了。

为了搞明白这几个reference,我查找了很多资料。现就WeakReference来进行深入讲解:

先看个例子:

package reference;

import java.lang.ref.WeakReference;

public class TestWeakReference {

public static void main(String[] args) {

Car car = new Car(22000,"silver");
WeakReference<Car> weakCar = new WeakReference<Car>(car);

int i=0;

while(true){
//System.out.print(car);
if(weakCar.get()!=null){
i++;
System.out.println("Object is alive for "+i+" loops - "+weakCar);
}else{
System.out.println("Object has been collected.");
break;
}
}
}

}


最后的运行结果为

“Object has been collected.”

也就是说对象最后还是被回收了。这是因为对于new出来的Car(22000,”silver”),GC线程发现已经跑到while循环中,指向它的强引用car没有被用到,只有一个弱引用weakCar还在。所以这个Car对象就被回收掉了。

所以在while循环中加下面这么一段话:

System.out.print(car);

Car对象就不会被回收掉了。

而SoftReference除了在GC回收前判断内存空间,其他的都与WeakReference一样。

因为有这个特性, soft reference比weak reference更加适合做cache objects的reference. 因为它可以尽可能的retain cached objects, 减少重建他们所需的时间和消耗.

以上内容来自不只是给面试加分 – Java WeakReference的理解与使用

为了理解GC在weakReference指向对象被回收时到底干了什么,我又查到了以下资料:

弱引用在GC的过程中,会被特殊处理。在GC的过程中,以copy gc为例,所有存活的强引用都会被拷到新的survivor区域中,但是弱引用不会被拷贝。同时会把WeakReference都使用它的discovered域串起来,在串的同时,把它的referent设置为 null,如下图所示。



WeakReference wr = new WeakReference(o);

第一种情况,当o已经是垃圾,也就是说,除了这个weak ref之外,再没有其他指向这个 o 的引用了。这种情况下,o就会被回收,并且wr的referent就会变成null,进而wr.get()就会是null。

第二种情况,当o不是垃圾,那么毫无疑问,o会被拷贝到survivor空间,这时JVM就不会再把wr放到discovered链表中去了,并且还会把o的新地址更新到wr的referent(更新地址是什么意义,请具体参考前边的Copy GC的文章),这时,弱引用仍然存在。

而PhantomReference的作用是:

PhantomReference 唯一的用处就是跟踪 referent何时被 enqueue 到 ReferenceQueue 中.

具体就不再继续深入了。到了后面会再讲解WeakHashMap的内容。

(6)Hashcode的作用。

ArrayList、LinkedList、Vector的区别。

String、StringBuffer与StringBuilder的区别。

Map、Set、List、Queue、Stack的特点与用法。

HashMap和HashTable的区别。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 面试