- 2、SoftNode 内部强引用K,弱引用真正的Value
*/
private HashMap<K, SoftNode<K, V>> temp;
public SoftHashMap() {
queue = new ReferenceQueue<>();
temp = new HashMap<>();
}
@Override
public V get(Object key) {
clearQueue();
// 通过 key进行取值,如果为null,返回null,否则返回 SoftNode 软引用的值
SoftNode softNode = temp.get(key);
return softNode == null ? null : (V) softNode.get();
}
@Override
public V put(K key, V value) {
clearQueue();
// 创建 SoftNode对象
SoftNode softNode = new SoftNode(key, value, queue);
// 返回key之前所对应的SoftNode对象,即oldSoftNode
SoftNode oldSoftNode = temp.put(key, softNode);
// 如果oldSoftNode为null,就返回null,否则就返回 oldSoftNode所软引用的 Value
return oldSoftNode == null ? null : (V) oldSoftNode.get();
}
@Override
public boolean containsKey(Object key) {
clearQueue();
return temp.containsKey(key);
}
@Override
public V remove(Object key) {
clearQueue();
SoftNode<K, V> remove = temp.remove(key);
return remove == null ? null : remove.get();
}
@Override
public int size() {
clearQueue();
return temp.size();
}
/**
-
通过软引用队列内的 SoftNode,获取Key,然后temp 清除此 Key
-
@see ReferenceQueue poll()
-
poll() – 类似于 stack 的pop(),移除并返回此对象
*/
private void clearQueue() {
SoftNode poll;
while ((poll = (SoftNode) queue.poll()) != null) {
temp.remove(poll.key);
}
}
/**
-
对V进行软引用的类
-
@param key,用于当 V 被回收后,temp 可以通过 key 进行移除
-
@param Value,真正的值
-
传入的queue,用于当Value被回收后,将 SoftNode对象放入 queue中,
-
以便于表示 某 SoftNode对象中的Value 已经被收回了。
*/
private class SoftNode<K, V> extends SoftReference {
K key;
public SoftNode(K k, V v, ReferenceQueue queue) {
super(v, queue);
key = k;
}
}
}
2、强引用与软引用的测试对比:
测试中可以明显的看到:
-
强引用时,加载的String更多,但会造成内存溢出;
-
弱引用时,由于弱引用的机制(内存满时会进行垃圾回收),不会造成内存溢出,但由于需要对String进行处理,所以加载的String没有强引用时多;
读者福利
由于篇幅过长,就不展示所有面试题了,感兴趣的小伙伴
更多笔记分享
[外链图片转存中…(img-QVMDylkl-1719156962713)]
[外链图片转存中…(img-6Bo4OtaL-1719156962714)]
[外链图片转存中…(img-pWA5uDZy-1719156962714)]
更多笔记分享
[外链图片转存中…(img-Sii4urOj-1719156962715)]