2010-11-07 12 views
16

मेरे पास मेरे एप्लिकेशन में एक छवि कैश है जिसे सॉफ़्ट रेफरेंस का उपयोग करके लागू किया गया है। Dalvik अपेक्षाकृत छोटे ढेर के साथ अनुप्रयोग शुरू करता है, और फिर मांग के मामले में इसे बढ़ाता है। लेकिन मैं शुरुआत से अपना ढेर आकार बड़ा करना चाहता हूं। ऐसा इसलिए है क्योंकि जब मेरे पास पहले से ही कैश में कुछ छवियां होती हैं, और एक गतिविधि शुरू होती है (उदाहरण के लिए) या अन्य शीर्ष मेमोरी मांग होती है, तो उस चरम मांग के लिए स्मृति देने के लिए मेरा कैश शुद्ध हो जाता है। नतीजतन, चोटी के बाद चले गए मेरे पास अभी भी 2-3 एमबी फ्री स्पेस है लेकिन मेरा कैश खाली है!एंड्रॉइड: रनटाइम पर ढेर आकार कैसे बढ़ाएं?

मैं इस समस्या के लिए जो समाधान देखता हूं वह एक बड़ा ढेर फोरहैंड आवंटित कर रहा है, यहां तक ​​कि 2-3 एमबी की चोटी की खपत के साथ भी इसमें कुछ कमरे की जगह है इसलिए मेरे सॉफ़्ट संदर्भों को शुद्ध नहीं किया गया है।

मुझे पता चला कि VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE) सहायक होगा। विशेष रूप से, Google उनके ऐप्स में उपयोग करता है, जैसा कि here बताया गया है। हालांकि, VMRuntime वर्ग को बहिष्कृत किया गया है और भविष्य में रिलीज में सार्वजनिक एपीआई से हटाया जाना कहा जाता है। तो setMinimumHeapSize एक स्थायी समाधान नहीं है।

फिर मैं स्टार्टअप पर अपने ढेर को बढ़ाने के लिए दलविक कैसे बना सकता हूं?

वर्तमान में मैं एक बड़ी सरणी आवंटित करके इसे जारी करके वास्तव में सीधे-सीधे और चीज तकनीक का उपयोग करता हूं। यह दलविक को ढेर बढ़ने के कारण बनाता है। हालांकि, मुझे यकीन है कि ऐसा करने का और अधिक शानदार तरीका होना चाहिए। क्या आप मुझे बता सकते हैं, कृपया?

+1

मुझे शक है आप को सार्वजनिक API – Falmarri

+0

गूगल मैप्स प्रतिबिंब का उपयोग करता है और इस API का उपयोग यह करने के लिए एक तरह से मिल जाएगा, मैं इस पोस्ट करते हुए कॉल :) – sherpya

उत्तर

6

ढेर आकार बढ़ाने के बजाय आप कुछ बेहतर कर सकते हैं। जैसा कि आपने कहा था कि आप अपने आवेदन में कैश बनाए रखते हैं जिसे सॉफ़्ट रेफरेंस का उपयोग करके कार्यान्वित किया जाता है।

private LruCache<String, Bitmap> bitmapCache; 
final int memClass; 
int cacheSize; 

memClass = ((ActivityManager) context.getSystemService(
    Context.ACTIVITY_SERVICE)).getMemoryClass(); 

वापसी वर्तमान डिवाइस का अनुमानित प्रति-अनुप्रयोग स्मृति वर्ग: सबसे अच्छी बात LruCache उपयोग करने के लिए आप इस तरह की कुछ बात कर सकते हैं। इससे आपको यह पता चलता है कि समग्र प्रणाली को सर्वोत्तम तरीके से काम करने के लिए आपको अपने आवेदन पर कितनी मेमोरी सीमा लागू करनी चाहिए। लौटाया गया मूल्य मेगाबाइट्स में है; बेसलाइन एंड्रॉइड मेमोरी क्लास 16 है (जो उन उपकरणों की जावा ढेर सीमा होती है); अधिक मेमोरी वाला कुछ डिवाइस 24 या उससे भी अधिक संख्या लौटा सकता है।

cacheSize = 1024 * 1024 * memClass/10; 
bitmapCache = new LruCache<String, Bitmap>(cacheSize) { 
    @Override 
    protected int sizeOf(String key, Bitmap value) { 
    return value.getHeight() * value.getRowBytes(); 
} 
}; 

यह अगर स्मृति LruCache जा स्मृति से अधिक है LruCache से बिटमैप छवियों को हटाने और उस में नई छवि लोड होगा।

0

मुझे नहीं लगता कि आप इस स्तर पर किसी डिवाइस की स्मृति को प्रभावित या प्रभावित कर सकते हैं। सिस्टम को अपनी बात करने दें और इसके खिलाफ मत जाओ। क्या गतिविधियां शुरू होने पर भी आपको सॉफ्ट रेफरेंस के साथ इतनी बड़ी छवि कैश रखने की आवश्यकता है?

आप इसे कैसे शेल्फ में किया जाता है जाँच करना चाहते हैं: देखना लाइन 82 http://code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/curiouscreature/android/shelves/util/ImageUtilities.java?r=26

+1

मैंने कभी नहीं कहा अपने कैश है के बारे में जानकारी खोज पाया बड़े। असल में यह कैश आकार पर निर्भर नहीं है - यहां तक ​​कि छोटे कैश के साथ भी यह काम नहीं करेगा, जैसा कि मैंने बताया है, उन स्मृति की वजह से। मैं ~ 100 आइटम 2-3 केबी की कैश रखता हूं - यह एक बड़ा कैश नहीं है लेकिन फिर भी यह हर बार साफ़ हो जाता है। मैंने पाया कि कुछ एंड्रॉइड संस्करणों में कचरा कलेक्टर में सॉफ़्ट रेफरेंस के साथ बग है: http://stackoverflow.com/questions/4014033 यह सॉफ्ट रेफरेंस-आधारित कैश को व्यावहारिक रूप से बेकार बनाता है। – JBM

2

में समस्या यह है कि SoftReferences जावा ढेर अंतरिक्ष में किया आवंटन के लिए उपयोगी होते हैं, लेकिन छवियों देशी रूप आवंटित किए जाते हैं, तो यह कैश प्रकार वास्तव में एंड्रॉइड पर काम नहीं करेगा।

+0

दरअसल, मैं अपने कैश में छवियों को बाइट एरे के रूप में संग्रहीत करता हूं क्योंकि वे सर्वर से प्राप्त होते हैं (कैश कनेक्शन स्तर पर होता है)। लेकिन वैसे भी, यह एक उपयोगी संकेत है - धन्यवाद! – JBM

+0

@ जेबीएम अगर आप उन्हें वहां स्टोर करते हैं, तो आप वास्तव में डबल रैम का उपयोग करते हैं जो आपको चाहिए, क्योंकि बिटमैप ऑब्जेक्ट्स अपने बाइट्स का उपयोग करते हैं। –

+0

यह एक पुराना विषय है, लेकिन मैं वैसे भी जवाब दूंगा। मेरे मामले में, सर्वर से प्राप्त सभी छवियों की केवल एक छोटी संख्या किसी भी पल में प्रदर्शित होती है। तो कोई डबल-रैम उपयोग नहीं है। वास्तव में, हम डिस्क पर पहले स्तर और स्मृति में दूसरा, छोटा, 2-स्तर कैश का उपयोग करते हैं। मेरा सवाल स्मृति को अनुकूलित करने के बारे में था। मैं अपनी गलती देखता हूं: मुझे अपने प्रश्न को और अधिक अमूर्त तरीके से पूछना चाहिए था; मुझे सर्वर और छवियों के बारे में कुछ भी नहीं कहना चाहिए था क्योंकि इससे लोगों को एक बॉक्स में सोचने लगता है। – JBM

4

यदि कैश सामान्य रूप से छोटा है, तो आप अपने ऐप का एक वैध पदचिह्न तय कर सकते हैं और सॉफ़्ट रेफरेंस के बिना अपना कैश बनाए रख सकते हैं।

उदाहरण के लिए एक साधारण कुल बाइट काउंटर द्वारा: बस सूची के शीर्ष पर उपयोग किए गए किसी भी तत्व को जोड़ें या स्थानांतरित करें, यदि यह नया है तो इसका आकार काउंटर पर जोड़ें। नीचे से हटाएं यदि कुल बाइट्स आपके नियम-थंब सीमा से अधिक है, जिससे आपका काउंटर कम हो जाता है। शायद LinkedHashMap कक्षा इसके लिए उपयोगी है: इसे HashMap जैसे कैश के रूप में उपयोग किया जा सकता है, लेकिन इसकी सूची भी एक सूची की तरह है।

1

आप ढेर आकार को गतिशील रूप से बढ़ा नहीं सकते हैं।

आप एंड्रॉइड का उपयोग करके अधिक उपयोग करने का अनुरोध कर सकते हैं: मेनिफेस्ट में bigHeap = "true", लेकिन हो सकता है कि आपको सामान्य से अधिक ढेर आकार न मिले, क्योंकि यह केवल एक अनुरोध है।

भी, आप देशी मेमोरी का उपयोग कर सकते हैं, इसलिए आप वास्तव में ढेर आकार सीमा को बाईपास करते हैं।

और यहाँ एक पुस्तकालय मैं इसे के लिए बनाया गया है::

यहाँ कुछ पदों मैं इसके बारे में बनाया है कर रहे हैं