मैं नक्शा बनाने के लिए मैपमेकर का उपयोग करना चाहता हूं जो बड़ी वस्तुओं को कैश करता है, यदि पर्याप्त मेमोरी नहीं है तो कैश से हटाया जाना चाहिए। इस छोटे डेमो कार्यक्रम ठीक से काम करने लगता है:कैश बनाने के लिए 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();
}
}
हालांकि, जब मैं अपने वास्तविक आवेदन में एक ही बात करते हैं, प्रविष्टियों मूल रूप से जैसे ही वे जुड़ जाते हैं कैश से निकाल रहे हैं। मेरे वास्तविक एप्लिकेशन में, मैं पूर्णांक को कुंजी के रूप में भी उपयोग करता हूं, और कैश किए गए मान डिस्क से पढ़ने वाले संग्रह ब्लॉक होते हैं जिनमें कुछ डेटा होता है। जहां तक मैं समझता हूं, कमजोर संदर्भ कूड़े-संग्रहित होते हैं जैसे ही वे अब उपयोग नहीं किए जाते हैं, इसलिए ऐसा लगता है क्योंकि कुंजी कमजोर संदर्भ हैं। अगर मैं इस तरह नक्शा बनाने:
data = new MapMaker()
.softValues()
.makeMap();
प्रविष्टियों कभी नहीं कचरा-एकत्र कर रहे हैं और मैं अपने परीक्षण कार्यक्रम में एक आउट-ऑफ-स्मृति त्रुटि मिलती है। TestValue प्रविष्टियों पर अंतिमकरण विधि कभी नहीं कहा जाता है। मैं निम्नलिखित करने के लिए परीक्षण प्रक्रिया बदल देते हैं:
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) {
}
}
}
प्रविष्टियों कैश और TestValue वस्तुओं पर finalizer कहा जाता है से हटा दिया जाता है, लेकिन कुछ समय बाद मैं भी एक-से-बाहर स्मृति त्रुटि मिलती है।
तो मेरा सवाल है: मानचित्र बनाने के लिए MapMaker का उपयोग करने का सही तरीका क्या है जिसे कैश के रूप में उपयोग किया जा सकता है? यदि मैं कमजोरकेज़ का उपयोग करता हूं तो जितनी जल्दी हो सके मेरे परीक्षण प्रोग्राम प्रविष्टियों को हटा नहीं देता है? क्या यह कैश मानचित्र में संदर्भ कतार जोड़ना संभव है?
किसी को पढ़ने में आसान बनाने के लिए कोड को संपादित कर सकते हैं? – nanda
मैं इससे थोड़ा आश्चर्यचकित हूं। मैंने 'softValues' का बिल्कुल वही तरीका उपयोग किया है और यह ठीक काम करता है, 'स्मृति कम होने पर' सॉफ्ट रेफरेंस को साफ़ किया जा रहा है। – finnw