我想使用MapMaker創建緩存大對象的映射,如果內存不足,應從緩存中刪除這些大對象, 。 這個小演示程序似乎很好地工作:使用MapMaker創建緩存
public class TestValue {
private final int id;
private final int[] data = new int[100000];
public TestValue(int id) {
this.id = id;
}
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalized");
}
}
public class Main {
private ConcurrentMap<Integer, TestValue> cache;
MemoryMXBean memoryBean;
public Main() {
cache = new MapMaker()
.weakKeys()
.softValues()
.makeMap();
memoryBean = ManagementFactory.getMemoryMXBean();
}
public void test() {
int i = 0;
while (true) {
System.out.println("Etntries: " + cache.size() + " heap: "
+ memoryBean.getHeapMemoryUsage() + " non-heap: "
+ memoryBean.getNonHeapMemoryUsage());
for (int j = 0; j < 10; j++) {
i++;
TestValue t = new TestValue(i);
cache.put(i, t);
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Main m = new Main();
m.test();
}
}
然而,當我做同樣的事情在我的實際應用中,條目 基本上從緩存,儘快爲他們添加刪除。在我的真實 應用程序中,我也使用整數作爲鍵,並且緩存值爲 從包含某些數據的磁盤讀取的歸檔塊。據I 明白,只要不再使用 就會被垃圾收集垃圾收集,所以這似乎是有意義的,因爲這些鍵是弱的 引用。如果我創建的地圖是這樣的:
data = new MapMaker()
.softValues()
.makeMap();
的條目是從來沒有垃圾收集和我在測試程序得到了內存不足的錯誤 。 TestValue條目 上的finalize方法永遠不會被調用。如果我改變了測試方法如下:
public void test() {
int i = 0;
while (true) {
for (final Entry<Integer, TestValue> entry :
data.entrySet()) {
if (entry.getValue() == null) {
data.remove(entry.getKey());
}
}
System.out.println("Etntries: " + data.size() + " heap: "
+ memoryBean.getHeapMemoryUsage() + " non-heap: "
+ memoryBean.getNonHeapMemoryUsage());
for (int j = 0; j < 10; j++) {
i++;
TestValue t = new TestValue(i);
data.put(i, t);
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
}
條目從緩存中,並在測試值 對象終結被稱爲刪除,但過了一段時間我也得到一個內存不足, 錯誤。
所以我的問題是:什麼是正確的方式來使用MapMaker創建一個 地圖,可以用作緩存?爲什麼我的測試程序不能儘快刪除 條目,如果我使用weakKeys?是否有可能將 添加引用隊列到緩存映射?
有人可以編輯代碼,使其更容易閱讀? – nanda 2010-07-09 10:27:34
我對此有點驚訝。我已經使用'softValues'完全相同的方式,並且它工作正常,當內存不足時,SoftReference被清除。 – finnw 2010-07-17 00:27:33