2012-05-20 13 views
28

मैं एंड्रॉइड विकास के लिए काफी नया हूं और मुझे जावा आउट ऑफ़ मेमोरी अपवाद को समझने की प्रतीत नहीं होती है। मुझे पता है कि इसका मतलब है कि मेरा ऐप वीएम बजट पर चला गया है लेकिन कई बार गुगल करने के बाद भी मुझे इस अवधारणा को समझने की प्रतीत नहीं होती है। मुझे डर है कि मेरा ऐप बहुत अधिक मेमोरी का उपयोग करता है क्योंकि मेरे पास प्रत्येक चयनकर्ता के लिए दो बिटमैप्स के साथ प्रति स्क्रीन छह बटन चयनकर्ता हैं जो गुण टैब के अनुसार लगभग 20 केबी हैं। मेरे रूट किए गए जी 2 एक्स पर मैंने वीएम बजट को 12 एमबी पर सेट किया है, मेरे फोन को फिर से शुरू किया है और बिना किसी समस्या के मेरे ऐप को चलाया है। मैं प्रत्येक ऑनस्ट्रोय() पर ड्रॉबल्स को अनबाइंडिंग कर रहा हूं और जीसी पर भी यहां दौड़ने के लिए संकेत दे रहा हूं। एमुलेटर में थोड़ी देर के लिए ऐप का उपयोग करने के बाद, मैं अपनी डीडीएमएस स्क्रीन पर "कारण जीसी" पर क्लिक करता हूं और परिणाम आईडी = 1, हीप आकार 6.133 एमबी, आवंटित 2.8 9 5 एमबी, नि: शुल्क 3.238 एमबी,% प्रयुक्त 47.20, # ऑब्जेक्ट्स 52,623।एंड्रॉइड समझना ढेर आकार

यह वह जगह है जहां मुझे नहीं पता कि क्या हो रहा है, मेरा एमुलेटर 24 एमबी वीएम पर सेट है। वह संख्या कहां है? मेरी वास्तविक समस्या यह है कि अगर मैं एम्यूलेटर को 16 एमबी वीएम पर सेट करता हूं तो मेरा ऐप आउट ऑफ़ मेमोरी अपवाद के साथ दूसरी गतिविधि पर क्रैश हो जाता है। यह मेरे फोन पर वीएम सेट के साथ 12 एमबी या मेरे पुराने एचटीसी मैजिक फोन पर 12 एमबी वीएम स्टॉक के साथ कैसे क्रैश नहीं होता है? क्या आप लोग सोचते हैं कि मेरा ऐप बहुत अधिक मेमोरी ले रहा है? मुझे नहीं पता कि उन डीडीएमएस नंबर अच्छे हैं या नहीं। आपके समय के लिए धन्यवाद।

मेरे कोड के लिए मेरे पास XML लेआउट में निर्दिष्ट प्रत्येक छवि है, मैं उन्हें श्रोताओं को जोड़ने के अलावा प्रोग्रामिंग के साथ कुछ भी नहीं करता हूं। मैं यहाँ पर कोड के इस बिट मिल गया है और मैं इसे हर गतिविधि मेरे पास है में शामिल किया है ...

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    unbindDrawables(findViewById(R.id.myRootLayout)); 
    System.gc(); 
} 

private void unbindDrawables(View view) { 
    if (view.getBackground() != null) { 
     view.getBackground().setCallback(null); 
    } 
    if (view instanceof ViewGroup && !(view instanceof AdapterView)) { 
     for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
      unbindDrawables(((ViewGroup) view).getChildAt(i)); 
     } 
     ((ViewGroup) view).removeAllViews(); 
    } 
} 

अन्यथा सब मुझे क्या करना बटन है कि पीएनजी पृष्ठभूमि को onClickListeners जोड़ने है। मैं सीखना चाहता हूं कि बटन पृष्ठभूमि को प्रोग्रामेटिक रूप से कैसे निर्दिष्ट किया जाए, लेकिन मुझे बटन इंटरैक्शन के अनुसार बटन पृष्ठभूमि बदलने के लिए, फोकस पर, फोकस, गैर-केंद्रित लेकिन दबाए गए आदि जैसे चयनकर्ता फ़ंक्शंस की आवश्यकता होती है। मैंने इस बारे में दस्तावेज़ों की समीक्षा की है लेकिन यह भारी लग रहा है, इसलिए मैंने सोचा कि मैं यहां ढेर के प्रबंधन की मूल बातें के साथ शुरू करूंगा और कोड में चयनकर्ताओं को निर्दिष्ट करने के लिए अपना रास्ता तैयार करूंगा। यह समझ में नहीं आता है लेकिन क्या स्मृति की आवंटन की "स्वस्थ" मात्रा है कि एक ऐप आउट ऑफ़ मेमोरी अपवाद के करीब बिना आवंटित किया जा सकता है? उदाहरण के लिए यदि कोई ऐप 6 एमबी आवंटित किया गया तो यह ठीक होना चाहिए लेकिन 8 एमबी इसे धक्का दे रहा है, क्या स्मृति आवंटन में ऐसी सीमाएं हैं? धन्यवाद, आपकी प्रतिक्रिया के लिए फिर से एलेक्स लॉकवुड मैं इसे पढ़ने और फिर से पढ़ने के लिए जा रहा हूं जब तक कि यह सामान मुझे समझ में नहीं आता है

उत्तर

50

जब आप अपने एमुलेटर/डिवाइस पर वीएम बजट सेट करते हैं, तो आप जो कर रहे हैं वह ढेर बता रहा है अधिकतम आकार होने की अनुमति है। रनटाइम पर, ढेर गतिशील रूप से आकार में बढ़ता है क्योंकि दल्विक वीएम ऑपरेटिंग सिस्टम से सिस्टम मेमोरी का अनुरोध करता है। दल्विक वीएम आम तौर पर अपेक्षाकृत छोटे ढेर को आवंटित करके शुरू होता है। फिर प्रत्येक जीसी चलाने के बाद यह देखने के लिए जांच करता है कि कितनी मुफ्त ढेर मेमोरी है। यदि कुल ढेर के लिए कुल ढेर का अनुपात बहुत छोटा है, तो दलविक वीएम तब ढेर में अधिकतम मेमोरी जोड़ देगा (अधिकतम कॉन्फ़िगर किए गए ढेर आकार तक)।

कहा जा रहा है कि, आप अपनी डीडीएमएस स्क्रीन पर "24 एमबी" क्यों नहीं देख रहे हैं, क्योंकि ढेर अपने अधिकतम आकार में नहीं उभरा है। यह एंड्रॉइड को हाथ से चलने वाले उपकरणों पर उपलब्ध स्मृति की पहले से ही कम मात्रा का अच्छा उपयोग करने की अनुमति देता है।

क्यों आपका आवेदन एम्यूलेटर पर दुर्घटनाग्रस्त हो रहा है, न कि आपके फोन पर, यह अजीब लगता है (क्या आप सुनिश्चित हैं कि संख्याएं सही हैं?)। आपको ध्यान में रखना चाहिए, हालांकि, स्मृति गतिशील रूप से प्रबंधित की जाती है और कुल स्मृति उपयोग कई बाहरी कारकों (गति/आवृत्ति जिस पर कचरा संग्रह किया जाता है, आदि) के आधार पर निर्धारित किया जाता है।

आखिरकार, ऊपर बताए गए कारणों के लिए, यह सुनिश्चित करना मुश्किल होगा कि आपका एप्लिकेशन ऊपर दी गई जानकारी की एक पंक्ति के आधार पर स्मृति का प्रबंधन कैसे करता है। हमें वास्तव में आपके कुछ कोड देखने की आवश्यकता होगी।OutOfMemoryError एस निश्चित रूप से चिंता करने योग्य हैं, इसलिए, मैं निश्चित रूप से आपके एप्लिकेशन के मेमोरी उपयोग को देखता हूं। एक चीज जिसे आप विचार कर सकते हैं BitmapFactory कक्षा का उपयोग कर inSampleSize पर कॉल के साथ रनटाइम पर अपनी बिटमैप छवियों का नमूना देना है। यह आपके ड्रॉइंग बिटमैप्स को लोड करने के लिए आवश्यक स्मृति की मात्रा को कम करने में मदद कर सकता है। या तो आप या आप अपने drawables के संकल्प को कम कर सकते हैं (हालांकि 20 केबी प्रत्येक मेरे लिए ठीक लगता है)।

+3

+1, बहुत ही जानकारीपूर्ण जवाब! –

+0

बहुत बहुत धन्यवाद! मैंने उससे बहुत कुछ सीखा। मैं प्रश्न के नीचे कुछ जानकारी जोड़ रहा हूं –

+0

पुन: संकल्प टिप्पणी "20 केबी प्रत्येक ठीक लगता है" - AFAIK, इससे कोई फ़र्क नहीं पड़ता कि * फ़ाइल आकार * क्या है (जो छवियों के लिए बेहतर होगा जो बेहतर हो) यह मायने रखता है कि * डायमेंशन * क्या हैं; स्मृति में, पूर्ण रंग के लिए, 4 बी प्रति पिक्सल ले जाएगा, है ना? इसलिए, जब आप इसे लोड करते हैं तो छवि को आकार देने के लिए महत्वपूर्ण है [एंड्रॉइड दस्तावेज़ - वास्तविक स्केल किए गए संस्करण को मेमोरी में लोड करें], वर्तमान डिवाइस के लिए वास्तविक आवश्यक आकार के आधार पर। – ToolmakerSteve

16

भले ही आपका एप्लिकेशन "24 एमबी" तक पहुंच न जाए (डिवाइस के भीतर बदलता है) ढेर सीमा में आपको अभी भी क्रैश हो सकता है क्योंकि एंड्रॉइड आपके ऐप के लिए ढेर स्थान बढ़ाने के लिए कुछ समय लेता है।

मेरी स्थिति में मैं थोड़ी सी मात्रा में कई छवियां बना रहा था और डंप कर रहा था।

अक्सर मुझे OutOfMemoryError मिल रहा था।

ऐसा लगता है कि एंड्रॉइड मेरे ऐप के लिए ढेर स्थान को बढ़ाने के लिए पर्याप्त तेज़ नहीं था।

मेरा मानना ​​है कि मैंने मैनिफेस्ट फ़ाइल में largeHeap सेटिंग का उपयोग करके इस समस्या को हल किया है। उस सेटिंग के साथ, एंड्रॉइड हर बार जब यह ढेर बढ़ता है, तो एंड्रॉइड अधिक खाली मेमोरी छोड़ देता है, जिससे मौजूदा सीमा को मारने का मौका कम हो जाता है।

मैं 24 एमबी सीमा का उपयोग नहीं करता लेकिन यह largeHeap conf काफी आसान था।

तुम बस अभी भी अपने AndroidManifest.xml

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" 
    android:largeHeap="true" 
    android:theme="@style/AppTheme" > 

के आवेदन टैग पर largeHeap="true" स्थापित करने के लिए, सुनिश्चित करें कि आप सावधान कर रहे हैं जब छवियों के साथ काम कर, जैसे @Alex लॉकवुड सलाह दी बनाने की जरूरत है।

+16

परम देखभाल के साथ bigHeap = "true" का उपयोग करें। चूंकि इसका उपयोग आपके ऐप परफॉर्मेंस को प्रतिकूल रूप से प्रभावित कर सकता है। क्योंकि आप अधिकतम ढेर सीमा बढ़ाने के लिए सिस्टम को बता रहे हैं। जब ऐसा होता है तो कचरा संग्रह के लिए अधिक समय लगेगा। यदि आप लॉग की जांच करते हैं तो आप देख सकते हैं कि जीसी विराम समय अधिक होगा। आदर्श रूप में यह 2-5ms के बीच होना चाहिए। इस मामले में यह 30-45ms तक भी भिन्न हो सकता है। तो बड़ी ढेर संपत्ति को सही पर सेट न करें क्योंकि आप स्मृति से बाहर हो रहे हैं। इसे अंतिम चरण के रूप में प्रयोग करें। अन्यथा यह एक परफॉर्मेंस हिट होगा। वास्तव में –

+0

। मेरे मामले में, मैं बड़े पैमाने पर उच्च गुणवत्ता वाली छवियों से निपट रहा हूं और बड़े हेप विकल्प का उपयोग करने से पहले, मैंने कोड को लागू किया है: - छवियों को नमूना - पूर्ण फिट करने के लिए छवियों का आकार बदलें - स्मृति से अप्रयुक्त छवियों को साफ़ करना - "डिस्क" में कैशिंग छवियां मुझे अभी भी समस्याएं थीं जो केवल बड़े हेप विकल्प के साथ हल की गई थीं। फिर भी, इसे सब कुछ करने के बाद ही उपयोग करें, जैसे @ सनालवर्गेस ने सलाह दी। – tbraun

+0

बस इसमें जोड़कर, मुझे अपने ऐप की मेमोरी के साथ बहुत सारे मुद्दे हैं, इसका आकार काफी बढ़ता है। यह इस बिंदु पर कुशलता से एक साथ स्थापित नहीं किया जा सकता है, लेकिन यह हेप सीमा को समाप्त करने में सक्षम होना चाहिए था। हालांकि यह कभी भी कई संसाधनों को जारी नहीं करेगा। किसी कारण से यह बड़े हेप विकल्प को लागू करने के बाद बहुत अच्छा करता है। बहुत बहुत धन्यवाद। –

संबंधित मुद्दे