एंड्रॉइड में वर्तमान मेमोरी उपयोग कैसे प्राप्त करें?


108

मैं / proc / meminfo का उपयोग किया है और आदेश प्रतिक्रिया पार्स की है। जब भी यह परिणाम दिखाता है कि:

मेमोटल: 94348 kB मेमफ्री: 5784 kB

माध्यम। यह दिखाता है कि केवल 5MB मुफ्त मेमोरी है। क्या यह एंड्रॉइड मोबाइल के साथ संभव है? मेरे मोबाइल पर केवल 5-6 एप्लिकेशन इंस्टॉल है और कोई अन्य कार्य नहीं चल रहा है। लेकिन फिर भी यह कमांड दिखाता है कि बहुत कम मुफ्त मेमोरी है।

क्या कोई इसे स्पष्ट कर सकता है? या Android में मेमोरी उपयोग करने का कोई अन्य तरीका है?


2
क्या आप प्रति डिवाइस या एप्लिकेशन के अनुसार निःशुल्क मेमोरी देखने का प्रयास कर रहे हैं? यदि एप्लिकेशन के अनुसार है, तो उसे ढेर-ए-ला पर गणना करने की आवश्यकता है Debug.getNativeHeapFreeSize()
इगोरगानापल्स्की

1
मुफ्त मेमोरी (रैम में) का उपयोग करके / proc / meminfo की गणना करने के लिए आपको मेम्फ्री , बफ़र्स , कैश्ड और स्वैच्च्ड का समुच्चय प्राप्त करना होगा । एंड्रॉइड द्वारा प्रदान किए गए इस उद्देश्य के लिए एक एपीआई है जो एपीआई 16 और वार्डों पर काम करता है। अगर आप पुराने APIs को टारगेट कर रहे हैं तो Meminfo मददगार है।
AB

जवाबों:


174

चेतावनी: यह उत्तर मेमोरी उपयोग / डिवाइस की उपलब्धता को मापता है। यह वह नहीं है जो आपके ऐप के लिए उपलब्ध है। यह मापने के लिए कि आपका APP क्या कर रहा है, और ऐसा करने के लिए PERMITTED है, Android डेवलपर के उत्तर का उपयोग करें


एंड्रॉइड डॉक्स - एक्टिविटी मैनजर.मोरीइन्फो

  1. parse / proc / meminfo कमांड। आप यहाँ संदर्भ कोड पा सकते हैं: Android में मेमोरी उपयोग प्राप्त करें

  2. नीचे दिए गए कोड का उपयोग करें और वर्तमान रैम प्राप्त करें:

    MemoryInfo mi = new MemoryInfo();
    ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    activityManager.getMemoryInfo(mi);
    double availableMegs = mi.availMem / 0x100000L;
    
    //Percentage can be calculated for API 16+
    double percentAvail = mi.availMem / (double)mi.totalMem * 100.0;
    

0x100000L संख्या की व्याख्या

1024 bytes      == 1 Kibibyte 
1024 Kibibyte   == 1 Mebibyte

1024 * 1024     == 1048576
1048576         == 0x100000

यह काफी स्पष्ट है कि संख्या का उपयोग बाइट्स से mebibyte में बदलने के लिए किया जाता है

पुनश्च: हमें केवल एक बार कुल मेमोरी की गणना करने की आवश्यकता है। इसलिए अपने कोड में केवल एक बार बिंदु 1 पर कॉल करें और उसके बाद, आप बिंदु 2 के कोड को दोहराव से कॉल कर सकते हैं।


मैं मेमोरी साइज़ चेक करना चाहता हूँ। मेमोरीइन्फो क्या है?
पिरभा डे

PIraba, इसका Android API वर्ग है। इसे यहां देखें। developer.android.com/reference/android/app/…
बादल

@SanjayJoshi क्योंकि बाइट में मेमोरी वेरिएबल में मीम चर शामिल है। 1024 बाइट्स 1 किलोवाट के बराबर और 1024 किलोबाइट्स 1 मेगाबाइट के बराबर होता है। तो 1024 * 1024 बराबर 1048576
रॉल्फ '

2
ऊपर डबल में कनवर्ट करें, और प्रतिशत में होगा 0
ब्लूहैंड

1
@ रॉल्फ R क्षमा करें, लेकिन 1024 बाइट्स एक किबिबाइट के बराबर होते हैं और 1024 किबिबाइट एक मिबाइट होते हैं। किलो और मेगा दशमलव उपसर्ग हैं। 1000 बाइट = 1 किलोबाइट। यह भी उत्तर में बताया गया गलत है।
जैकसनऑफ़ 1

88

यह आपकी परिभाषा पर निर्भर करता है कि आप किस मेमोरी क्वेरी को प्राप्त करना चाहते हैं।


आमतौर पर, आप हीप मेमोरी की स्थिति जानना चाहते हैं, क्योंकि यदि यह बहुत अधिक मेमोरी का उपयोग करता है, तो आपको OOM मिलता है और ऐप को क्रैश कर देता है।

इसके लिए, आप अगले मान देख सकते हैं:

final Runtime runtime = Runtime.getRuntime();
final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L;
final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB;

जितना अधिक "usedMemInMB" वैरिएबल "maxHeapSizeInMB" के करीब availHeapSizeInMBजाता है , उतना ही शून्य हो जाता है , उतना ही करीब आपको OOM मिलता है। (स्मृति विखंडन के कारण, आपको OOM पहले यह शून्य तक पहुँच सकता है।)

स्मृति उपयोग का DDMS उपकरण भी यही दर्शाता है।


वैकल्पिक रूप से, वास्तविक रैम का उपयोग होता है, जो कि पूरे सिस्टम का कितना उपयोग करता है - इसकी गणना करने के लिए स्वीकृत उत्तर देखें ।


अपडेट: चूंकि एंड्रॉइड ओ आपके ऐप को देशी रैम का उपयोग करता है (कम से कम बिटमैप्स स्टोरेज के लिए, जो आमतौर पर विशाल मेमोरी उपयोग का मुख्य कारण है), और न केवल ढेर, चीजें बदल गई हैं, और आपको कम ओओएम मिलता है (क्योंकि हीप में अब बिटमैप्स नहीं हैं, यहाँ देखें ), लेकिन आपको मेमोरी के उपयोग पर नज़र रखनी चाहिए अगर आपको संदेह है कि आपके पास मेमोरी लीक है। एंड्रॉइड ओ पर, यदि आपके पास मेमोरी लीक है जो पुराने संस्करणों पर ओओएम का कारण होना चाहिए था, तो ऐसा लगता है कि यह बस आप को पकड़ने में सक्षम होने के बिना क्रैश हो जाएगा। स्मृति उपयोग के लिए जाँच कैसे करें:

val nativeHeapSize = Debug.getNativeHeapSize()
val nativeHeapFreeSize = Debug.getNativeHeapFreeSize()
val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize

लेकिन मेरा मानना ​​है कि आईडीई के प्रोफाइलर का उपयोग करना सबसे अच्छा हो सकता है, जो ग्राफ का उपयोग करके वास्तविक समय में डेटा दिखाता है।

तो एंड्रॉइड ओ पर अच्छी खबर यह है कि कई बड़े बिटमैप को संग्रहीत करने के ओओएम के कारण क्रैश होने के लिए बहुत मुश्किल है, लेकिन बुरी खबर यह है कि मुझे नहीं लगता कि रनटाइम के दौरान इस तरह के मामले को पकड़ना संभव है।


EDIT: Debug.getNativeHeapSize()समय के साथ बदलाव दिखता है , क्योंकि यह आपको आपके ऐप की कुल अधिकतम मेमोरी दिखाता है। तो उन कार्यों का उपयोग केवल प्रोफाइलर के लिए किया जाता है, यह दिखाने के लिए कि आपका ऐप कितना उपयोग कर रहा है।

यदि आप वास्तविक कुल और उपलब्ध देशी रैम प्राप्त करना चाहते हैं, तो इसका उपयोग करें:

val memoryInfo = ActivityManager.MemoryInfo()
(getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).getMemoryInfo(memoryInfo)
val nativeHeapSize = memoryInfo.totalMem
val nativeHeapFreeSize = memoryInfo.availMem
val usedMemInBytes = nativeHeapSize - nativeHeapFreeSize
val usedMemInPercentage = usedMemInBytes * 100 / nativeHeapSize
Log.d("AppLog", "total:${Formatter.formatFileSize(this, nativeHeapSize)} " +
        "free:${Formatter.formatFileSize(this, nativeHeapFreeSize)} " +
        "used:${Formatter.formatFileSize(this, usedMemInBytes)} ($usedMemInPercentage%)")

वाह। इतना सरल, फिर भी इतना सच!
रैन

वास्तविक मेमोरी उपयोग क्या है? इसलिए इस मामले में इस्तेमाल किया गया है इस मामले में ऐप का वास्तविक मेमोरी उपयोग नहीं है? जब मैं इस कोड का उपयोग करता हूं, तो यह दिखाता है कि मेरा उपयोग 50mb जैसा है लेकिन जब मैं फोन सेटिंग में जाता हूं और वहां मेमोरी उपयोग देखता हूं, तो मेरा ऐप 100mb का है। यह अंतर क्यों है?
बैटमसी

1
@batmaci हीप मेमोरी ऐप की कुल मेमोरी उपयोग का एक हिस्सा है। देशी मेमोरी उपयोग भी है, जो आमतौर पर वेबपेज, गेम और कुछ भारी उद्देश्यों के लिए उपयोग किया जाता है। आमतौर पर ऐप्स को केवल ढेर मेमोरी पर देखने की आवश्यकता होती है, क्योंकि यह डिवाइस रैम की तुलना में काफी कम है, और यदि वे उस तक पहुंचते हैं, तो ऐप क्रैश हो जाएगा (भले ही मुफ्त रैम बहुत हो)।
एंड्रॉयड डेवलपर

यह एक आदर्श कोड स्निपेट है, OOM की जाँच के लिए बहुत उपयोगी है, बहुत बहुत धन्यवाद।
aolphn

@AlphaOF धन्यवाद, लेकिन एंड्रॉइड ओ पर चीजें बदल गई हैं। मैंने वहां की स्थिति से मिलान करने के लिए उत्तर अपडेट किया है।
Android डेवलपर

29

वर्तमान में चल रहे एप्लिकेशन की मेमोरी उपयोग की गणना करने का एक तरीका इस प्रकार है :

public static long getUsedMemorySize() {

    long freeSize = 0L;
    long totalSize = 0L;
    long usedSize = -1L;
    try {
        Runtime info = Runtime.getRuntime();
        freeSize = info.freeMemory();
        totalSize = info.totalMemory();
        usedSize = totalSize - freeSize;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return usedSize;

}

4
यह एक सरल तरीका है, लेकिन जैसा कि यह दस्तावेज में इंगित किया गया था, रनटाइम क्लास फ्रीमोरी () विधि, वर्तमान प्रोग्राम या एप्लिकेशन के लिए उपलब्ध मेमोरी को वापस करती है। इसलिए उपयोग करते समय इसके बारे में जागरूक रहें।
अक्सेल फातिह

2
@Peter - हां, यह "गलत" है, क्योंकि यह एक अलग प्रश्न का उत्तर देता है जो कि पूछा गया था। दूसरी ओर, यह "सही" है, जिसके लिए एक ऐप डेवलपर को आमतौर पर जानने की आवश्यकता होती है: यह शायद ही कभी मायने रखता है कि डेविस पर मेमोरी की समग्र स्थिति क्या है - यदि उपयोगकर्ता ने बहुत सारे एप्लिकेशन चलाए हैं, तो ओएस को सबसे अधिक उपयोग करना चाहिए इसकी स्मृति - अन्यथा यह अक्षम है। ओएस को यह जानने की जरूरत है कि स्वीकृत उत्तर क्या देता है, यह जानने के लिए कि हाल ही में उपयोग नहीं किए गए ऐप को मारना कब शुरू करें। लेकिन एक ऐप प्रोग्रामर को यह जानने की जरूरत है कि THIS उत्तर (और एंड्रॉइड डेवलपर के समान उत्तर) आपको क्या कहता है, बनाम runtime.maxMemory।
टूलमेकरसेव

यह समाधान केवल रनटाइम द्वारा ऐप के संपर्क में आने वाली मेमोरी पर काम करता है। यह पूरे सिस्टम मेमोरी के बारे में अंतर्दृष्टि नहीं देता है क्योंकि ओपी की आवश्यकता है।
एबी

कई उपकरणों पर (उदाहरण के लिए Xiaomi) Runtime.freeMemory()0 Runtime.totalMemory()लौटाता है और वर्तमान में केवल मेमोरी आवंटित करता है।
आर्टेम

17

दूसरा तरीका (वर्तमान में मेरे G1 पर 25MB मुफ्त दिखा रहा है):

MemoryInfo mi = new MemoryInfo();
ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem / 1048576L;

हे एलेक्स, आपकी मदद के लिए बहुत बहुत धन्यवाद! 1 और सवाल। यह कोड मुझे उपलब्ध RAM देता है। मैं टोटल रैम भी प्रदर्शित करना चाहता हूं। कैसे प्राप्त करें?
बादल

@ बाडल मैं इसके लिए जावा एपीआई नहीं जानता। स्टार्स टू पार्सिंग / प्रोक / मेमिनफो।
यानचेन

12

लिनक्स का मेमोरी मैनेजमेंट दर्शन है "फ्री मेमोरी इज़ बर्बाद मेमोरी"।

मुझे लगता है कि अगली दो पंक्तियों से पता चलेगा कि "बफ़र्स" में कितनी मेमोरी है और "कैश्ड" कितनी है। हालांकि दोनों के बीच अंतर है (कृपया यह मत पूछें कि क्या अंतर है :) वे दोनों लगभग फ़ाइल डेटा और मेटाडेटा को कैश करने के लिए उपयोग की जाने वाली मेमोरी की मात्रा में जोड़ते हैं।

लिनक्स सिस्टम पर मेमोरी को फ्री करने के लिए एक अधिक उपयोगी गाइड free(1)कमांड है; मेरे डेस्कटॉप पर, यह इस तरह से जानकारी रिपोर्ट करता है:

$ मुक्त-एम
             कुल उपयोग मुक्त साझा बफ़र्स कैश्ड
मेम: 5980 1055 4924 0 91 374
- / + बफ़र्स / कैश: 589 5391
स्वैप: ६३४ap ० ६३४

+/- बफ़र्स / कैश: लाइन मैजिक लाइन है, यह रिपोर्ट करता है कि मुझे वास्तव में सक्रिय रूप से आवश्यक प्रक्रिया मेमोरी के लगभग 589 megs, और 'फ्री' मेमोरी के लगभग 5391 megs मिले हैं, इस अर्थ में कि 91 + 374 मेगाबाइट बफ़र्स / कैश्ड मेमोरी को फेंक दिया जा सकता है अगर मेमोरी को कहीं और अधिक लाभप्रद रूप से उपयोग किया जा सकता है।

(मेरी मशीन लगभग तीन घंटे से ऊपर है, लगभग कुछ भी नहीं है, लेकिन स्टैकओवरफ्लो है, यही वजह है कि मेरे पास इतनी मुफ्त मेमोरी है।)

यदि एंड्रॉइड के साथ जहाज नहीं है free(1), तो आप /proc/meminfoफ़ाइल के साथ गणित स्वयं कर सकते हैं ; मुझे सिर्फ free(1)आउटपुट फॉर्मेट पसंद है । :)


1
@Igor, तो आप cat /proc/meminfoइसके बजाय करना चाहते हैं । यह कहीं अधिक विस्तृत जानकारी दी है, लेकिन MemFreeBuffers, और Cachedसबसे महत्वपूर्ण लाइनों की संभावना है।
सरनॉल्ड

6

मैं कुछ लेखन का संदर्भ देता हूं।

संदर्भ:

इस getMemorySize () विधि को MemorySize लौटाया गया है जिसमें कुल और मुफ़्त मेमोरी का आकार है।
मैं इस कोड पर पूरी तरह विश्वास नहीं करता।
यह कोड LG G3 cat.6 (v5.0.1) पर परीक्षण कर रहा है

    private MemorySize getMemorySize() {
        final Pattern PATTERN = Pattern.compile("([a-zA-Z]+):\\s*(\\d+)");

        MemorySize result = new MemorySize();
        String line;
        try {
            RandomAccessFile reader = new RandomAccessFile("/proc/meminfo", "r");
            while ((line = reader.readLine()) != null) {
                Matcher m = PATTERN.matcher(line);
                if (m.find()) {
                    String name = m.group(1);
                    String size = m.group(2);

                    if (name.equalsIgnoreCase("MemTotal")) {
                        result.total = Long.parseLong(size);
                    } else if (name.equalsIgnoreCase("MemFree") || name.equalsIgnoreCase("Buffers") ||
                            name.equalsIgnoreCase("Cached") || name.equalsIgnoreCase("SwapFree")) {
                        result.free += Long.parseLong(size);
                    }
                }
            }
            reader.close();

            result.total *= 1024;
            result.free *= 1024;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    private static class MemorySize {
        public long total = 0;
        public long free = 0;
    }

मुझे पता है कि Pattern.compile () महंगी लागत है इसलिए आप इसके कोड को कक्षा के सदस्य के पास ले जा सकते हैं।


3

मैंने एंड्रॉइड सोर्स ट्री को देखा।

अंदर। Com.android.server.am। एक्टिविट मेनेजरसेवर.जाव (android.app के द्वारा उजागर की जाने वाली आंतरिक सेवा। एक्टिविटी मैनजर )।

public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
    final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
    final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
    outInfo.availMem = Process.getFreeMemory();
    outInfo.totalMem = Process.getTotalMemory();
    outInfo.threshold = homeAppMem;
    outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
    outInfo.hiddenAppThreshold = hiddenAppMem;
    outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
            ProcessList.SERVICE_ADJ);
    outInfo.visibleAppThreshold = mProcessList.getMemLevel(
            ProcessList.VISIBLE_APP_ADJ);
    outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
            ProcessList.FOREGROUND_APP_ADJ);
}

Android.os के अंदर। Process.java

/** @hide */
public static final native long getFreeMemory();

/** @hide */
public static final native long getTotalMemory();

यह JNI विधि को android_util_Process.cpp से कॉल करता है

निष्कर्ष

MemoryInfo.availMem = MemFree + in / proc / meminfo में कैश किया गया।

टिप्पणियाँ

कुल मेमोरी एपीआई स्तर 16 में जोड़ी गई है।


1

आप डीडीएमएस टूल का भी उपयोग कर सकते हैं जो एंड्रॉइड एसडीके का हिस्सा है। यह जावा कोड और देशी c / c ++ कोड के मेमोरी आवंटन प्राप्त करने में मदद करता है।


0
public static boolean isAppInLowMemory(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);

    return memoryInfo.lowMemory;
}

0
final long usedMemInMB=(runtime.totalMemory() - runtime.freeMemory()) / 1048576L;
final long maxHeapSizeInMB=runtime.maxMemory() / 1048576L;
final long availHeapSizeInMB = maxHeapSizeInMB - usedMemInMB;

यह एक अजीब कोड है। यह MaxMemory - (TotalMemory - freeMemory) लौटाता है। यदि फ्रीमोरी 0 के बराबर है, तो कोड मैक्समोरी - टोटल मीमोरी को लौटा देगा, इसलिए यह अधिक या बराबर हो सकता है। 0. फ्रीमोरी का उपयोग क्यों नहीं किया जाता है?


0

यहाँ आपके ऐप के मेमोरी उपयोग को देखने का एक और तरीका है:

adb shell dumpsys meminfo <com.package.name> -d

नमूना उत्पादन:

Applications Memory Usage (kB):
Uptime: 2896577 Realtime: 2896577

** MEMINFO in pid 2094 [com.package.name] **
                   Pss  Private  Private  Swapped     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     3472     3444        0        0     5348     4605      102
  Dalvik Heap     2349     2188        0        0     4640     4486      154
 Dalvik Other     1560     1392        0        0
        Stack      772      772        0        0
    Other dev        4        0        4        0
     .so mmap     2749     1040     1220        0
    .jar mmap        1        0        0        0
    .apk mmap      218        0       32        0
    .ttf mmap       38        0        4        0
    .dex mmap     3161       80     2564        0
   Other mmap        9        4        0        0
      Unknown       76       76        0        0
        TOTAL    14409     8996     3824        0     9988     9091      256

 Objects
               Views:       30         ViewRootImpl:        2
         AppContexts:        4           Activities:        2
              Assets:        2        AssetManagers:        2
       Local Binders:       17        Proxy Binders:       21
    Death Recipients:        7
     OpenSSL Sockets:        0

 SQL
         MEMORY_USED:        0
  PAGECACHE_OVERFLOW:        0          MALLOC_SIZE:        0

समग्र स्मृति उपयोग के लिए:

adb shell dumpsys meminfo

https://developer.android.com/studio/command-line/dumpsys#meminfo

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