को गहन रूप से अंतिम रूप देने के लिए मैं एक खोज लाइब्रेरी का उपयोग कर रहा हूं जो खोज संभाल ऑब्जेक्ट को खोलने की सलाह देता है जिससे क्वेरी कैश का लाभ हो सकता है। उस समय मैंने देखा है कि कैश फूला हुआ है (कुछ सौ मेग्स और बढ़ता रहता है) और ओओएम ने किक शुरू कर दिया। इस कैश की सीमाओं को लागू करने का कोई तरीका नहीं है और न ही यह योजना है कि यह कितनी मेमोरी का उपयोग कर सकती है। इसलिए मैंने एक्सएमएक्स सीमा बढ़ा दी है, लेकिन यह समस्या का केवल एक अस्थायी समाधान है।सॉफ़्ट रेफरेंस रेफरेंस
आखिरकार मैं इस ऑब्जेक्ट को java.lang.ref.SoftReference
बनाने के लिए सोच रहा हूं। तो अगर सिस्टम मुफ्त मेमोरी पर कम चलाता है, तो यह वस्तु को जाने देगा और मांग पर एक नया बनाया जाएगा। इससे ताजा शुरुआत के बाद कुछ गति कम हो जाएगी, लेकिन ओओएम को मारने से यह एक बेहतर विकल्प है।
सॉफ़्ट रेफरेंस के बारे में मुझे एकमात्र समस्या यह है कि उनके संदर्भों को अंतिम रूप देने का कोई साफ तरीका नहीं है। मेरे मामले में, खोज संभाल को नष्ट करने से पहले मुझे इसे बंद करने की आवश्यकता है, अन्यथा सिस्टम फ़ाइल डिस्क्रिप्टर से बाहर हो सकता है। जाहिर है, मैं इस हैंडल को किसी अन्य ऑब्जेक्ट में लपेट सकता हूं, उस पर एक फाइनलाइज़र लिख सकता हूं (या एक संदर्भक्यू/फैंटॉम रिफरेंस पर हुक) और जाने दो। लेकिन हे, इस ग्रह में हर एक लेख फाइनलाइजर्स का उपयोग करने के खिलाफ सलाह देता है, और विशेष रूप से - फ़ाइल हैंडल को मुक्त करने के लिए अंतिमकर्ताओं के खिलाफ (उदा। प्रभावी जावा संस्करण II, पृष्ठ 27.)।
तो मैं कुछ हद तक परेशान हूं। क्या मुझे इन सभी सलाहयों को ध्यान से अनदेखा करना चाहिए और आगे बढ़ना चाहिए। अन्यथा, क्या कोई अन्य व्यावहारिक विकल्प हैं? अग्रिम में धन्यवाद।
संपादित करें # 1: नीचे दिए गए पाठ को टॉम Hawtin द्वारा सुझाए गए कुछ कोड का परीक्षण करने के बाद जोड़ा गया था। मेरे लिए, ऐसा प्रतीत होता है कि कोई सुझाव काम नहीं कर रहा है या मुझे कुछ याद आ रहा है। कोड यह रहा: अगर मैं (ऊपर कोड के रूप में) -Xmx10m
और SoftReferences साथ ऊपर टुकड़ा चलाने
class Bloat { // just a heap filler really
private double a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z;
private final int ii;
public Bloat(final int ii) {
this.ii = ii;
}
}
// as recommended by Tom Hawtin
class MyReference<T> extends SoftReference<T> {
private final T hardRef;
MyReference(T referent, ReferenceQueue<? super T> q) {
super(referent, q);
this.hardRef = referent;
}
}
//...meanwhile, somewhere in the neighbouring galaxy...
{
ReferenceQueue<Bloat> rq = new ReferenceQueue<Bloat>();
Set<SoftReference<Bloat>> set = new HashSet<SoftReference<Bloat>>();
int i=0;
while(i<50000) {
// set.add(new MyReference<Bloat>(new Bloat(i), rq));
set.add(new SoftReference<Bloat>(new Bloat(i), rq));
// MyReference<Bloat> polled = (MyReference<Bloat>) rq.poll();
SoftReference<Bloat> polled = (SoftReference<Bloat>) rq.poll();
if (polled != null) {
Bloat polledBloat = polled.get();
if (polledBloat == null) {
System.out.println("is null :(");
} else {
System.out.println("is not null!");
}
}
i++;
}
}
, मैं मुद्रित is null :(
की टन हो रही है। लेकिन अगर मैं MyReference
के साथ कोड को प्रतिस्थापित करता हूं (MyReference के साथ दो पंक्तियों को अपूर्ण करता हूं और सॉफ़्ट रेफरेंस वाले लोगों को टिप्पणी करता हूं) तो मुझे हमेशा ओओएम मिलता है।
जैसा कि मैंने सलाह से समझा, MyReference
के अंदर हार्ड संदर्भ होने से ReferenceQueue
पर ऑब्जेक्ट को रोकना नहीं चाहिए, है ना?
क्या आपके कोड को ठीक करना संभव होगा ताकि यह संकलित हो सके? जैसे MyReference कन्स्ट्रक्टर ब्लोट रेफरेंस तर्क लेता है और उसे हार्डरफ को असाइन करना होता है, लेकिन हार्डरफ एक पूरी तरह से अलग प्रकार का है (ResourceThatMustBeClosed)। साथ ही, क्या आप विस्तार कर सकते हैं कि संसाधनों को प्राप्त करने के बाद ब्लोट अभी भी जरूरी क्यों है? पीएस मुझे इतना जरूरतमंद नहीं होगा अगर इस प्रश्न में कोई बोनस प्वाइंट संलग्न नहीं था: पी – mindas
मैंने कोड अपडेट किया है, और (उम्मीद है) एक स्पष्ट जोड़ा यह कैसे काम करता है इसका स्पष्टीकरण? यदि नहीं, तो मुझे बताएं ... –
कोड तय किया गया है ताकि यह संकलित हो। बस इसे खाली कक्षा में फेंक दें, और उपयुक्त जोड़ें आयात। –