Chcę użyć programu MapMaker do utworzenia mapy przechowującej duże obiekty, , która powinna zostać usunięta z pamięci podręcznej, jeśli nie ma wystarczającej ilości pamięci. Ten mały program demo wydaje się działać prawidłowo:Używanie programu MapMaker do utworzenia pamięci podręcznej
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();
}
}
Jednakże gdy zrobić to samo w mojej prawdziwej aplikacji, wpisy są zasadzie usuwane z pamięci podręcznej tak szybko, jak są one dodawane. W mojej prawdziwej aplikacji używam również liczb całkowitych jako kluczy, a wartości buforowane to bloki archiwalne odczytywane z dysku zawierającego pewne dane. Jeśli chodzi o I , słabe referencje nie są już używane, ponieważ nie są już używane, ponieważ nie są już używane, więc są one słabe, ponieważ są to słabe referencje o numerach od . Jeśli utworzyć mapę takiego:
data = new MapMaker()
.softValues()
.makeMap();
Wpisy są nigdy śmieci zebrane i otrzymuję out-of-memory błąd w moim programie testowym. Metoda finalizacji na rekordach TestValue nigdy nie jest wywoływana. Jeśli mogę zmienić metodę testową do następujących:
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) {
}
}
}
wpisy są usuwane z pamięci podręcznej i finalizatora na testValue obiektów nazywa, ale po jakimś czasie również uzyskać out-of-memory błąd.
Moje pytanie brzmi: jaki jest właściwy sposób użycia MapMaker do utworzenia mapy , która może być używana jako pamięć podręczna? Dlaczego mój program testowy nie usuwa wpisów tak szybko, jak to możliwe, jeśli używam weakKeys? Czy można dodać kolejkę referencyjną do mapy pamięci podręcznej?
ktoś może edytować kod, aby ułatwić czytać? – nanda
Jestem trochę zaskoczony tym. Użyłem 'softValues' dokładnie w ten sam sposób i działało dobrze, a' SoftReference 's jest czyszczony, gdy pamięć kończy się. – finnw