राम एक ऐप का अधिकतम कितनी मात्रा में उपयोग कर सकता है?


145

मैं एंड्रॉइड ऑपरेटिंग सिस्टम के मेमोरी प्रबंधन से संबंधित इस प्रश्न को लेकर काफी उत्सुक हूं इसलिए मुझे उस विषय पर काफी विस्तृत उत्तर की उम्मीद है।

मैं क्या जानना चाहूंगा:

  • क्या है स्मृति की अधिकतम राशि (में मेगाबाइट / के रूप में प्रतिशत कुल रैम) ऐसे Android ऐप्लिकेशन (है कि एक प्रणाली एप्लिकेशन नहीं है) का उपयोग कर सकते हैं?
  • क्या Android संस्करणों के बीच कोई अंतर हैं ?
  • क्या डिवाइस के निर्माता के विषय में कोई मतभेद हैं ?

और सबसे महत्वपूर्ण रूप से:

  • क्या माना जाता है / यह उस पर निर्भर करता है जब यह सिस्टम पर आता है यह निर्धारित करता है कि कोई ऐप रनटाइम में कितना रैम का उपयोग कर सकता है (यह मानते हुए कि प्रति ऐप अधिकतम मेमोरी स्थिर संख्या नहीं है)?

मैंने अब तक क्या सुना है (2013 तक):

  • शुरुआती Android उपकरणों में 16MB का प्रति-ऐप कैप था
  • बाद में यह टोपी बढ़कर 24MB या 32MB हो गई

मुझे क्या उत्सुक बनाता है:

इन दोनों की सीमा बहुत कम है।

मैंने अभी हाल ही में अपने डिवाइस रैम की जांच करने के लिए Android टास्क मैनेजर डाउनलोड किया है । मैंने जो देखा है वह यह है कि लगभग 40-50 मेगाबाइट रैम का उपयोग करने वाले अनुप्रयोग हैं, जो कि 32 एमबी के बताए गए रैम के अधिकतम उपयोग से अधिक है। तो एंड्रॉइड यह कैसे निर्धारित करता है कि ऐप कितनी रैम का उपयोग कर सकता है? यह कैसे संभव है कि ऐप्स उस सीमा से अधिक हों?

इसके अलावा, मैंने देखा कि लगभग 30-40 मेगाबाइट्स का उपयोग करते समय मेरा क्रैश (सिस्टम द्वारा मार दिया गया) के कुछ ऐप एक OutOfememoryException के साथ । दूसरी ओर, मेरे पास अपने फोन पर 100 एमबी और कुछ समय के बाद (शायद मेमोरी लीक के कारण) अधिक चलने वाले ऐप हैं जो दुर्घटनाग्रस्त नहीं होते या मारे नहीं जाते। तो यह स्पष्ट रूप से ऐप पर ही निर्भर करता है जब यह निर्धारित करने की बात आती है कि रैम को कितना बख्शा जा सकता है। यह कैसे हो सकता है? (मैंने 768 एमबी रैम के साथ एचटीसी वन एस के साथ अपने परीक्षण किए)

अस्वीकरण: मैं किसी भी तरह से Android टास्क मैनेजर ऐप से संबद्ध नहीं हूं।

जवाबों:


119

अधिकतम मात्रा में मेमोरी (मेगाबाइट में / कुल रैम के प्रतिशत के रूप में) जो एक एंड्रॉइड एप्लिकेशन (जो सिस्टम ऐप नहीं है) का उपयोग कर सकता है?

यह डिवाइस द्वारा भिन्न होता है। getMemoryClass()परActivityManager आप डिवाइस अपने कोड पर चल रहा है के लिए मूल्य दे देंगे।

क्या Android संस्करणों के बीच कोई अंतर हैं?

हाँ, इंसोफ़र के रूप में OS की आवश्यकताओं में वर्षों से वृद्धि हुई है, और उपकरणों को मिलान के लिए समायोजित करना है।

क्या डिवाइस के निर्माता के विषय में मतभेद हैं?

हां, निर्माता उपकरणों का निर्माण करते हैं, और आकार डिवाइस द्वारा भिन्न होता है।

कौन से "पक्ष कारकों" को ध्यान में रखा जाता है जब यह निर्धारित करने की बात आती है कि ऐप कितनी रैम का उपयोग कर सकता है?

मुझे नहीं पता कि "साइड फैक्टर" का क्या मतलब है।

प्रारंभिक उपकरणों में 16 एमबी की प्रति-ऐप कैप थी; बाद में डिवाइस 24 एमबी या 32 एमबी तक बढ़ गए

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

यह कैसे संभव है कि ऐप्स उस सीमा से अधिक हों?

आप मानते हैं कि उस ऐप का लेखक जानता है कि वह क्या कर रहा है। उस पर विचार करना एक ऐप का मेमोरी उपयोग एक कोर एंड्रॉइड इंजीनियर के लिए निर्धारित करना मुश्किल है , मैं यह नहीं मानूंगा कि प्रश्न में ऐप आवश्यक रूप से विशेष रूप से सटीक परिणाम प्रदान कर रहा है।

कहा जा रहा है कि, मूल कोड (NDK) ढेर सीमा के अधीन नहीं है। और, एंड्रॉइड 3.0 के बाद से, ऐप्स "बड़े हीप" का अनुरोध कर सकते हैं, आमतौर पर सैकड़ों एमबी रेंज में, लेकिन ज्यादातर ऐप्स के लिए यह खराब रूप माना जाता है।

इसके अलावा, मैंने देखा कि मेरे कुछ ऐप लगभग 30-40 मेगाबाइट का उपयोग करते समय एक OutOfMemoryException के साथ क्रैश होते हैं।

ध्यान रखें कि एंड्रॉइड कचरा कलेक्टर एक कॉम्पैक्टिंग कचरा कलेक्टर नहीं है। अपवाद वास्तव में होना चाहिए CouldNotFindSufficientlyLargeBlockOfMemoryException, लेकिन वह शायद बहुत चिंताजनक माना जाता था। OutOfMemoryExceptionइसका मतलब है कि आप अपने अनुरोधित ब्लॉक को आवंटित नहीं कर सकते हैं , न कि आपने अपने ढेर को पूरी तरह से समाप्त कर दिया है।


मैं टेबल के बारे में नहीं समझ सकता, मेरे पास एक्सपीरिया एक्स मोबाइल है जिसका रिज़ॉल्यूशन 1080 x 1920 है जो कि बड़ा रिज़ॉल्यूशन है, और एक अन्य डिवाइस सैमसंग टैब 4 जो कि रिज़ॉल्यूशन 800 x 1280 है, इसलिए इसका समान रैम पर कब्जा करें, कृपया मेरा मार्गदर्शन करें क्योंकि मोबाइल आता है 3 जीबी रैम और टैब 1.5 जीबी रैम के साथ आता है, इसलिए टैबलेट बड़ी स्क्रीन के कारण बड़े रैम पर कब्जा कर लेता है?
राहुल मंडालिया

@RahulMandaliya: मुझे खेद है, लेकिन मुझे आपकी चिंता नहीं है या इस सवाल का क्या करना है। आप एक अलग स्टैक ओवरफ्लो प्रश्न खोलने की इच्छा कर सकते हैं जहां आप विस्तार से बताते हैं कि आपकी चिंता क्या है।
कॉमन्सवेयर जूल

15

यह 2018 का अंत है इसलिए चीजें बदल गई हैं।

सबसे पहले: अपना ऐप चलाएं और Android Studio में Android Profiler टैब खोलें। आप देखेंगे कि यह कितनी मेमोरी खपत करता है, आपको आश्चर्य होगा लेकिन यह बहुत सारी रैम आवंटित कर सकता है।

साथ ही यहाँ एक बेहतरीन लेख है आधिकारिक में है जिसमें मेमोरी प्रोइलर का उपयोग करने के बारे में विस्तृत निर्देश दिए गए हैं जो आपको आपके स्मृति प्रबंधन का गहराई से विवरण दे सकते हैं।

लेकिन ज्यादातर मामलों में, आपका नियमित एंड्रॉइड प्रोफाइलर आपके लिए पर्याप्त होगा।

यहाँ छवि विवरण दर्ज करें

आमतौर पर, एक ऐप 50Mb RAM आवंटन के साथ शुरू होता है, लेकिन मेमोरी में कुछ फ़ोटो लोड करने पर तुरंत 90Mb तक उछल जाता है। जब आप पहले से देखे गए फ़ोटो (3,5Mb प्रत्येक) के साथ एक ViewPager के साथ गतिविधि खोलते हैं, तो आप सेकंड में 190Mb आसानी से प्राप्त कर सकते हैं।

लेकिन इसका मतलब यह नहीं है कि आपके पास स्मृति प्रबंधन के साथ समस्याएँ हैं।

सबसे अच्छी सलाह जो मैं दे सकता हूं वह है दिशा-निर्देशों और सर्वोत्तम प्रथाओं का पालन करना, छवि लोडिंग (ग्लाइड, पिकासो) के लिए शीर्ष पुस्तकालयों का उपयोग करना और आप ठीक होंगे।


लेकिन अगर आपको कुछ करने की आवश्यकता है और आपको वास्तव में यह जानने की आवश्यकता है कि आप कितनी मेमोरी मैन्युअल रूप से आवंटित कर सकते हैं तो आप कुल मुफ्त मेमोरी प्राप्त कर सकते हैं और उसमें से पूर्व-निर्धारित हिस्से (% में) की गणना कर सकते हैं। मेरे मामले में, मुझे मेमोरी में डिक्रिप्ट किए गए फ़ोटो को कैश करने की आवश्यकता थी, इसलिए मुझे सूची के माध्यम से उन्हें हर उपयोगकर्ता स्लाइड को डीक्रिप्ट करने की आवश्यकता नहीं है।

इस प्रयोजन के लिए आप LruCache वर्ग का उपयोग करने के लिए तैयार उपयोग कर सकते हैं । यह एक कैश क्लास है जो स्वचालित रूप से ट्रैक करता है कि आपकी ऑब्जेक्ट कितनी मेमोरी (या इंस्टेंस की संख्या) आवंटित करती है और अपने उपयोग के इतिहास द्वारा हाल ही में रखने के लिए सबसे पुराने को हटा देती है। यहां इसका उपयोग करने के तरीके पर एक महान ट्यूटोरियल है।

मेरे मामले में, मैंने कैश के 2 उदाहरण बनाए: अंगूठे और संलग्नक के लिए। उन्हें सिंगलटन एक्सेस के साथ स्थिर बना दिया ताकि वे पूरे ऐप में विश्व स्तर पर उपलब्ध हों।

कैश क्लास:

public class BitmapLruCache extends LruCache<Uri, byte[]> {

    private static final float CACHE_PART_FOR_THUMBS_PRC = 0.01f; // 1% (Nexus 5X - 5Mb)
    private static final float CACHE_PART_FOR_ATTACHMENTS_PRC = 0.03f;// 3% (Nexus 5X - 16Mb)
    private static BitmapLruCache thumbCacheInstance;
    private static BitmapLruCache attachmentCacheInstance;

public static synchronized BitmapLruCache getDecryptedThumbCacheInstance() {
    if (thumbCacheInstance == null) {

        int cacheSize = getCacheSize(CACHE_PART_FOR_THUMBS_PRC);
    //L.log("creating BitmapLruCache for Thumb with size: " + cacheSize + " bytes");
        thumbCacheInstance = new BitmapLruCache(cacheSize);
        return thumbCacheInstance;
    } else {
        return thumbCacheInstance;
    }
}

public static synchronized BitmapLruCache getDecryptedAttachmentCacheInstance() {
    if (attachmentCacheInstance == null) {

        int cacheSize = getCacheSize(CACHE_PART_FOR_ATTACHMENTS_PRC);
    //            L.log("creating BitmapLruCache for Attachment with size: " + cacheSize + " bytes");
        attachmentCacheInstance = new BitmapLruCache(cacheSize);
        return attachmentCacheInstance;
    } else {
        return attachmentCacheInstance;
    }
}

private BitmapLruCache(int maxSize) {
    super(maxSize);
}

public void addBitmap(Uri uri, byte[] bitmapBytes) {
    if (get(uri) == null && bitmapBytes != null)
        put(uri, bitmapBytes);
}

public byte[] getBitmap(Uri uri) {
    return get(uri);
}


@Override
protected int sizeOf(Uri uri, byte[] bitmapBytes) {
    // The cache size will be measured in bytes rather than number of items.
    return bitmapBytes.length;
}
}

यह है कि मैं उपलब्ध मुक्त रैम की गणना करता हूं और मैं इसे कितना काट सकता हूं:

private static int getCacheSize(float partOfTotalFreeMemoryToUseAsCache){
    final long maxMemory = Runtime.getRuntime().maxMemory();
    //Use ... of available memory for List Notes thumb cache
    return (int) (maxMemory * partOfTotalFreeMemoryToUseAsCache);
}

और यह है कि मैं कैश्ड छवि प्राप्त करने के लिए एडेप्टर में इसका उपयोग करता हूं:

byte[] decryptedThumbnail = BitmapLruCache.getDecryptedThumbCacheInstance().getBitmap(thumbUri);

और कैसे मैंने इसे कैश इन बैकग्राउंड थ्रेड (नियमित रूप से AsyncTask) में सेट किया:

BitmapLruCache.getDecryptedThumbCacheInstance().addBitmap(thumbUri, thumbBytes); 

मेरा ऐप एपीआई 19+ को लक्षित करता है ताकि डिवाइस पुराने न हों और उपलब्ध रैम के ये अंश मेरे मामले में (1% और 3%) कैश के लिए पर्याप्त हैं।

मजेदार तथ्य: एंड्रॉइड के पास आपके ऐप को आवंटित मेमोरी की मात्रा प्राप्त करने के लिए कोई एपीआई या अन्य हैक नहीं है, इसकी गणना विभिन्न कारकों के आधार पर फ्लाई पर की जाती है।


PS मैं एक स्थिर वर्ग फ़ील्ड का उपयोग कैश रखने के लिए कर रहा हूं लेकिन नवीनतम Android दिशानिर्देशों के अनुसार इसके लिए ViewModel आर्किटेक्चर घटक का उपयोग करने की सिफारिश की गई है ।


12

स्क्रीन आकार और Android संस्करण के आधार पर प्रति एप्लिकेशन मेमोरी सीमाएं यहां हैं: https://drive.google.com/file/d/0B7Vx1OvzrLa3Y0R0X1BZbUpicGc/view?usp=singing

स्रोत: Android संगतता डाउनलोड http://source.android.com/compatibility/downloads.html ; संगतता परिभाषा दस्तावेज़ (CDD), अनुभाग वर्चुअल मशीन संगतता या रनटाइम संगतता


2
ड्राइव url पहुंच की अनुमति मांगता है
sil_grave
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.