SoftReference vs WeakReference and Cache Implement

本文通过实现两种不同的缓存——软引用缓存和弱引用缓存,比较了它们在不同内存压力下的表现。当堆内存紧张时,使用弱引用的缓存会更快地出现缓存未命中。

SoftReference vs WeakReference and Cache Implementation

The main difference between  SoftReferences and  WeakReferences is that  SoftReferences are less aggressive. 
WeakReference tells the Garbage Collector that it can remove an object because there's no need to give it long live, instead a SoftReference tells the Garbage Collector that an object can stay in memory as long as it has no memory needs. A  SoftReference, for this reason, is a better candidate than a WeakReference to implement a Cache. 
In this post we are going to compare two different caches: the first made with SoftReferences and the second made with WeakReferences. Both the caches work in this manner:
  • Cache hit:vthe system return an entry;
  • Cache missed: the system retrieves the entry out of the cache and then it puts the entry in the cache before it returns.

In the code shown below, there are two classes called  ImageLoader. The former makes use of a cache implemented with SoftReference (SoftReferenceCache), the latter makes use of a cache implemented with WeakReference (WeakReferenceCache). As you can see if a  cache hit occurs the entry is returned and if a  cache missed occurs, a new ValueCache is created and put in the cache. Actually this is an escamotage because ValueCache is usually retrieved in a different manner. 

ImageLoader.java (SoftReferenceCache) 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
packagecom.simonefolinojavablog.softreferencecache;
 
importjava.util.logging.Level;
 
publicclassImageLoader {
 
 privatestaticSoftReferenceCache<String, ValueCache> cache =newSoftReferenceCache<String, ValueCache>();
 
 publicstaticValueCache getImage(String key) {
   
  ValueCache result =null;
 
  ValueCache valueCache = (ValueCache) cache.get(key);
 
  if(valueCache ==null) {
   ProjectLogger.PROJECT_LOGGER.getLogger().log(Level.INFO,"entry: "+ key +" result: cache miss");
   ValueCache newValue =newValueCache();
   newValue.setKey(key);
   cache.put(key, newValue);
   result = newValue;
  }else{
   ProjectLogger.PROJECT_LOGGER.getLogger().log(Level.INFO,"entry: "+ key +" result: cache hit");
  }
  returnresult;
 }
}

SoftReferenceCache.java 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
packagecom.simonefolinojavablog.softreferencecache;
 
importjava.lang.ref.SoftReference;
importjava.util.HashMap;
 
publicclassSoftReferenceCache<KextendsComparable<K>, V> {
 
 privateHashMap<K, SoftReference<V>> map =newHashMap<K, SoftReference<V>>();
  
 publicV get(K key) {
  SoftReference<V> softReference = map.get(key);
 
  if(softReference ==null) {
   returnnull;
  }
  returnsoftReference.get();
 }
 
 publicvoidput(K key, V value) {
  map.put(key,newSoftReference<V>(value));
 }
 
}
ImageLoader.java (WeakReferenceCache) 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
packagecom.simonefolinojavablog.weakreferencecache;
 
importjava.util.logging.Level;
 
publicclassImageLoader {
 
 privatestaticWeakReferenceCache<String, ValueCache> cache =newWeakReferenceCache<String, ValueCache>();
 
 publicstaticValueCache getImage(String key) {
 
  ValueCache result =null;
 
  ValueCache valueCache = (ValueCache) cache.get(key);
 
  if(valueCache ==null) {
   ProjectLogger.PROJECT_LOGGER.getLogger().log(Level.INFO,"entry: "+ key +" result: cache miss");
   ValueCache newValue =newValueCache();
   newValue.setKey(key);
   cache.put(key, newValue);
   result = newValue;
  }else{
   ProjectLogger.PROJECT_LOGGER.getLogger().log(Level.INFO,"entry: "+ key +" result: cache hit");
 
  }
  returnresult;
 }
 
}

WeakReferenceCache.java 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
packagecom.simonefolinojavablog.weakreferencecache;
 
importjava.lang.ref.WeakReference;
importjava.util.HashMap;
 
publicclassWeakReferenceCache<KextendsComparable<K>, V> {
 
 privateHashMap<K, WeakReference<V>> map =newHashMap<K, WeakReference<V>>();
  
 publicV get(K key) {
 
  WeakReference<V> WeakReference = map.get(key);
 
  if(WeakReference ==null) {
   returnnull;
  }
  returnWeakReference.get();
 }
 
 publicvoidput(K key, V value) {
  map.put(key,newWeakReference<V>(value));
 }
 
}
These two different caches have different behaviour. Suppose that the Heap increases because of many Strong References, then the cache made with WeakReferences returns many  cache miss sooner than the cache made with SoftReferences. 

In a future post i'll describe the usage of  WeakHashMap

转载于:https://my.oschina.net/u/138995/blog/223626

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值