[ध्यान दें कि (जैसा कि कॉमन्सवेयर नीचे बताए गए हैं) इस उत्तर में पूरा दृष्टिकोण केवल 2.3.x (जिंजरब्रेड) तक लागू होता है। हनीकॉम बिटमैप डेटा के रूप में वीएम ढेर में आवंटित किया गया है।]
बिटमैप डेटा वीएम ढेर में आवंटित नहीं किया गया है। वीएम हीप (जो छोटा है) में इसका एक संदर्भ है, लेकिन अंतर्निहित स्कीया ग्राफिक्स लाइब्रेरी द्वारा मूल ढेर में वास्तविक डेटा आवंटित किया जाता है।
दुर्भाग्य से, बिटमैपफैक्टरी.decode की परिभाषा ...() का कहना है कि अगर छवि डेटा को डीकोड नहीं किया जा सकता है, तो यह शून्य हो जाता है, स्किया कार्यान्वयन (या जावा कोड और स्कीया के बीच जेएनआई गोंद) लॉग करता है संदेश जो आप देख रहे हैं ("वीएम हमें xxxx बाइट्स आवंटित नहीं करेगा") और फिर भ्रामक संदेश "बिटमैप आकार वीएम बजट से अधिक" के साथ आउटऑफमेमरी अपवाद फेंकता है।
समस्या वीएम ढेर में नहीं है बल्कि मूल ढेर में है। नाट्य ढेर को चल रहे अनुप्रयोगों के बीच साझा किया जाता है, इसलिए मुक्त स्थान की मात्रा इस बात पर निर्भर करती है कि अन्य एप्लिकेशन क्या चल रहे हैं और उनके बिटमैप उपयोग। लेकिन, यह देखते हुए कि बिटमैप फैक्ट्री वापस नहीं आएगी, आपको यह पता लगाने का एक तरीका चाहिए कि कॉल करने से पहले कॉल सफल होने जा रहा है या नहीं।
देशी ढेर के आकार की निगरानी करने के लिए दिनचर्या हैं (डीबग क्लास प्राप्त करने के तरीके को देखें)। हालांकि, मुझे पता चला है कि GetHativeHeapFreeSize() और getNativeHeapSize() विश्वसनीय नहीं हैं। तो मेरे अनुप्रयोगों में से एक जो गतिशील रूप से बड़ी संख्या में बिटमैप्स बनाता है, मैं निम्न कार्य करता हूं।
देशी ढेर आकार प्लेटफ़ॉर्म द्वारा भिन्न होता है।तो स्टार्टअप पर, हम अधिकतम अनुमत वीएम ढेर आकार की जांच करने के लिए अधिकतम स्वीकार्य देशी ढेर आकार निर्धारित करते हैं। [जादू संख्या 2.1 और 2.2 पर परीक्षण द्वारा निर्धारित किया गया है, और अन्य API स्तरों पर अलग हो सकता है।]
long mMaxVmHeap = Runtime.getRuntime().maxMemory()/1024;
long mMaxNativeHeap = 16*1024;
if (mMaxVmHeap == 16*1024)
mMaxNativeHeap = 16*1024;
else if (mMaxVmHeap == 24*1024)
mMaxNativeHeap = 24*1024;
else
Log.w(TAG, "Unrecognized VM heap size = " + mMaxVmHeap);
फिर हर बार जब हम BitmapFactory कॉल करने की आवश्यकता हम प्रपत्र का चेक द्वारा कॉल पूर्व में होना।
long sizeReqd = bitmapWidth * bitmapHeight * targetBpp/8;
long allocNativeHeap = Debug.getNativeHeapAllocatedSize();
if ((sizeReqd + allocNativeHeap + heapPad) >= mMaxNativeHeap)
{
// Do not call BitmapFactory…
}
ध्यान दें कि heapPad तथ्य यह है कि एक) मूल निवासी ढेर आकार की रिपोर्टिंग "सॉफ्ट" है के लिए अनुमति देने के लिए एक जादुई संख्या है और ख) हम अन्य एप्लिकेशन के लिए स्थानीय ढेर में कुछ जगह छोड़ना चाहते हैं। हम वर्तमान में 3 * 1024 * 1024 (यानी 3 एमबाइट्स) पैड के साथ चल रहे हैं।
[यह] (http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object/14731953#14731953) मदद कर सकता है! –