软引用对象,在响应内存需要时,由垃圾回收器决定是否清除此对象。软引用对象最常用于实现内存敏感的缓存
软可到达对象的所有软引用都要保证在虚拟机抛出 OutOfMemoryError
之前已经被清除。
只要软引用的指示对象是强可到达对象,即正在实际使用的对象,就不会清除软引用
public class SoftHashMap<K, V> extends AbstractMap<K, V> implements Map<K, V> {
private static final int DEFAULT_INITIAL_CAPACITY = 16;
private static final int MAXIMUM_CAPACITY = 1 << 30;
private Entry[] table;
private final ReferenceQueue<K> queue = new ReferenceQueue<K>();
private static final Object NULL_KEY = new Object();
private int size;
public SoftHashMap() {
table = new Entry[DEFAULT_INITIAL_CAPACITY];
}
/**
* @param key
* @param value
* @return
*/
@SuppressWarnings("unchecked")
public V put(K key, V value) {
Entry[] tab = getTable();
Entry temp;
for (int j = 0; j < tab.length; j++) {
temp = tab[j];
if (temp == null) continue;
V oldKey = (V) temp.getKey();
if (key == oldKey) {
temp.setValue(value);
return (V) temp.getValue();
}
temp = null;
}
tab[size] = new Entry<K, V>(key, value, queue);
if (++size >= table.length) resize(table.length << 1);
return value;
}
/**
* @param newCapacity
*/
void resize(int newCapacity) {
Entry[] newTable = new Entry[newCapacity];
System.arraycopy(table, 0, newTable, 0, newTable.length);
table = newTable;
}
/**
* @param h
* @param length
* @return
*/
static int indexFor(int h, int length) {
return h & (length - 1);
}
/**
* @param key
* @return
*/
private int hash(Object key) {
return key.hashCode() & table.length;
}
/**
* @return
*/
private Entry[] getTable() {
expungeStaleEntries();
return table;
}
/**
*
*/
private void expungeStaleEntries() {
Entry<K, V> e;
while ((e = (Entry<K, V>) queue.poll()) != null) {
e = null;
size--;
}
}
/**
* @param key
* @return
*/
private static Object maskNull(Object key) {
return (key == null ? NULL_KEY : key);
}
/**
* @return
*/
public Set<java.util.Map.Entry<K, V>> entrySet() {
expungeStaleEntries();
Set<Map.Entry<K, V>> entrys = new HashSet<Map.Entry<K, V>>();
for (int i = 0; i < table.length; i++) {
if (table[i] == null) continue;
entrys.add(table[i]);
}
return entrys;
}
public String toString(){
return entrySet().toString();
}
private static class Entry<K, V> extends SoftReference<K> implements Map.Entry<K, V> {
private V value;
public Entry(K k, V v, ReferenceQueue queue) {
super(k, queue);
this.value = v;
}
public K getKey() {
return super.get();
}
public V getValue() {
return value;
}
public V setValue(V value) {
V oldvalue = value;
this.value = value;
return oldvalue;
}
public boolean equals(Object o) {
if (!(o instanceof Map.Entry)) return false;
Map.Entry e = (Map.Entry) o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2))) return true;
}
return false;
}
public int hashCode() {
Object k = getKey();
Object v = getValue();
return ((k == null ? 0 : k.hashCode()) ^ (v == null ? 0 : v.hashCode()));
}
public String toString() {
return getKey() + "=" + getValue();
}
}
public static void main(String[] args) throws Exception {
SoftHashMap<Object, Object> softHashMap = new SoftHashMap<Object, Object>();
Object key1 = new String("asdfasdf"); // 堆中的对象是可以被垃圾回收的,而栈中基本变量,引用变量,是在跳出所在的语句块时!
// 基本类型变量或对象变量所在栈内存被系统自动释放!并且内存空间能够立即被释放!
// Object key1 = "sadfasdf";
Object value1 = "B";
Object key2 = "D"; // 栈变量是不会被垃圾回收器收集的
Object value2 = "B";
Object key3 = "C";
Object value3 = "B";
softHashMap.put(key1, value1);
softHashMap.put(key2, value2);
softHashMap.put(key3, value3);
softHashMap.put(key3, "asdfadfasd");
key3 = null;
// key2 = null;
// key1 = null;
System.gc();
Thread.sleep(1000);
Set<Map.Entry<Object, Object>> set = softHashMap.entrySet();
for (Map.Entry<Object, Object> entry : set) {
System.out.println("===" + entry.getValue());
}
}
}
分享到:
相关推荐
通常,我们会创建一个软引用对象,将实际的缓存数据作为参数传入,然后将软引用对象放入一个映射结构(如HashMap)中。当需要访问缓存时,首先检查映射中是否存在对应的软引用,如果存在,则尝试通过软引用获取实际...
// 创建一个HashMap用于存储软引用的Bitmap对象 Map, SoftReference<Bitmap>> imageCache = new HashMap(); // 加载图片到Bitmap对象 Bitmap bitmap = BitmapFactory.decodeStream(inputStream); // 创建...
通过创建一个`SoftReference<Bitmap>`实例并将Bitmap对象保存在`HashMap`中,我们可以在需要时快速访问图片,而当内存紧张时,软引用的对象会被自动清理,防止内存溢出。 软引用可以与`ReferenceQueue`一起使用,当...
这个类通常包含一个HashMap来存储URL与SoftReference的映射关系。 2. 当需要加载图片时,首先检查HashMap中是否存在对应的SoftReference。如果存在且Bitmap未被回收,直接返回Bitmap;否则,启动一个新的后台任务...
1. 创建图片缓存类:创建一个缓存类,例如`BitmapCache`,它包含一个SoftReference数组或者使用HashMap存储SoftReference。这样可以存储图片对象,同时允许在内存紧张时释放缓存。 2. 实现异步加载:使用AsyncTask...
为避免这个问题,可以使用弱引用(WeakReference)或软引用(SoftReference)来引用外部对象,或者在适当时候手动释放引用。 在Android开发中,组件的生命周期管理至关重要。BroadcastReceiver、ContentObserver、...
本项目通过源码实现了一个简单的高速缓存,展示了其在多线程并发环境下的性能优势。 在Java中,高速缓存的实现通常依赖于数据结构如哈希表(HashMap)或并发容器如ConcurrentHashMap。哈希表提供快速的查找和插入...
1. **缓存管理**:首先,类中定义了一个`HashMap`类型的成员变量`imageCache`,用于存储已加载过的图片的软引用(`SoftReference<Drawable>`)。软引用允许Java垃圾回收机制在内存不足时自动清理这些对象,从而避免...
3. **WeakReference/SoftReference**: 在内存管理中,弱引用和软引用可以用来解决缓存对象占用过多内存的问题。弱引用的对象在垃圾回收器运行时会被立即清除,而软引用的对象会在系统内存不足时才被回收。使用这些...
- 使用弱引用(WeakReference)、软引用(SoftReference)或虚引用(PhantomReference):这些引用不会阻止对象被垃圾收集,可以在需要时访问对象,但在内存紧张时允许GC回收。 - 注意线程局部变量:线程局部变量...
除了以上提到的情况,还有其他可能导致内存泄漏的因素,例如线程局部变量(ThreadLocal)未被清理,或者过度使用软引用(SoftReference)、弱引用(WeakReference)等。为防止内存泄漏,开发者应关注以下几点: - ...
1. **内存缓存**:为了加速图片加载,我们创建了一个内存缓存,使用HashMap存储图片的SoftReference对象。SoftReference是一种弱引用,当系统内存不足时,这些对象可能会被垃圾回收,从而释放内存。这样可以防止内存...
在Android开发中,内存泄漏是一个常见但严重的问题,它可能导致应用性能下降,甚至崩溃。为了帮助开发者有效地检测和解决这个问题,一个名为LeakCanary的开源项目应运而生。LeakCanary是一款专门为Android设计的内存...
- **软引用(SoftReference)**:使用软引用来管理图像对象,这样当系统内存紧张时,这些对象可以被垃圾回收机制回收。 #### 2. 文件缓存 - **缓存目录**:利用`Context.getExternalCacheDir()`和`Context....
- **get()**:当查找一个键时,如果在缓存中找到,将该键对应的节点移动到链表头部,并返回值。 - **put()**:向缓存中插入键值对时,首先检查是否已满。若满,则移除最不常使用的节点(链表尾部),然后将新节点...
更优的方案是使用软引用(`SoftReference`)或者可回收的`Bitmap`选项(`BitmapOptions.inPurgeable`)来避免内存溢出。 2. **加载队列管理**:通过`PhotosQueue`类来管理图片的加载队列,确保每个`ImageView`只关联...
当一个类加载器被销毁时,其加载的所有类和实例应当随之被回收。但在某些情况下,如使用了WeakReference、SoftReference等弱引用,或者有线程局部变量(ThreadLocal)未正确清理,就可能导致类加载器无法被回收,...
- **弱引用与软引用**:利用Java提供的`WeakReference`和`SoftReference`机制,可以让垃圾回收器在内存紧张时自动回收不经常使用的缓存数据。 ##### 3.2 数据更新 除了内存占用之外,数据的有效性也是缓存技术中的...
- 使用软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)可以帮助更好地管理对象的生命周期。 ### 进一步的性能优化策略 #### 系统资源利用的进一步考虑 1. **系统负载与资源分配**...