Programing

Android에서 현재 메모리 사용량을 얻는 방법은 무엇입니까?

lottogame 2020. 8. 18. 08:06
반응형

Android에서 현재 메모리 사용량을 얻는 방법은 무엇입니까?


나는 / proc / meminfo를 사용하고 명령 응답을 구문 분석했지만 결과는 다음과 같습니다.

메모리 합계 : 94348 kB 메모리 없음 : 5784 kB

방법. 5MB의 여유 메모리 만 있음을 보여줍니다. 안드로이드 모바일로 가능합니까? 내 모바일에 5-6 개의 애플리케이션 만 설치되어 있고 다른 작업은 실행되지 않습니다. 그러나 여전히이 명령은 사용 가능한 메모리가 거의 없음을 보여줍니다.

누군가 이것을 명확히 할 수 있습니까? 또는 안드로이드에서 메모리 사용량을 얻는 다른 방법이 있습니까?


주의 :이 답변은 장치의 메모리 사용량 / 사용 가능 여부를 측정합니다. 이것은 귀하의 앱에서 사용할 수있는 것이 아닙니다. 앱이 수행하는 작업을 측정하고 수행 할 수 있도록 허용 하려면 Android 개발자의 답변을 사용하십시오 .


Android 문서-ActivityManager.MemoryInfo

  1. parse / proc / meminfo 명령. 여기에서 참조 코드를 찾을 수 있습니다. Android에서 메모리 사용량 가져 오기

  2. 아래 코드를 사용하고 현재 RAM을 얻으십시오.

    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

숫자가 바이트에서 메비 바이트로 변환하는 데 사용된다는 것은 분명합니다.

추신 : 총 메모리를 한 번만 계산하면됩니다. 따라서 코드에서 포인트 1을 한 번만 호출 한 다음 그 후에 포인트 2의 코드를 반복적으로 호출 할 수 있습니다.


얻고 자하는 메모리 쿼리의 정의에 따라 다릅니다.


일반적으로 힙 메모리의 상태를 알고 싶습니다. 메모리를 너무 많이 사용하면 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수록 0에 가까울수록 OOM이 가까워집니다. (메모리 조각화로 인해 0에 도달하기 전에 OOM이 발생할 수 있습니다.)

그것은 또한 메모리 사용량의 DDMS 도구가 보여주는 것입니다.


또는 전체 시스템이 사용하는 실제 RAM 사용량 이 있습니다.이를 계산 하려면 허용 된 답변참조하십시오 .


업데이트 : Android O는 앱이 기본 RAM (적어도 메모리 사용량이 큰 주된 이유 인 Bitmaps 저장소의 경우)을 사용하도록 만들기 때문에 힙뿐만 아니라 상황이 변경되었으며 OOM이 줄어들 기 때문입니다. 힙에 더 이상 비트 맵이 포함되어 있지 않습니다. 여기 에서 확인 하십시오 ).하지만 메모리 누수가 의심되는 경우에도 메모리 사용을 주시해야합니다. Android O에서 이전 버전에서 OOM을 유발해야하는 메모리 누수가있는 경우 잡을 수없는 상태에서 충돌이 발생하는 것 같습니다. 메모리 사용량을 확인하는 방법은 다음과 같습니다.

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

하지만 그래프를 사용하여 실시간으로 데이터를 보여주는 IDE의 프로파일 러를 사용하는 것이 가장 좋습니다.

따라서 Android O의 좋은 소식은 너무 많은 큰 비트 맵을 저장하는 OOM으로 인해 충돌이 발생하기가 훨씬 더 어렵다는 것입니다. 그러나 나쁜 소식은 런타임 중에 이러한 경우를 포착 할 수 없다고 생각한다는 것입니다.


현재 실행중인 애플리케이션의 메모리 사용량을 계산하는 방법은 다음과 같습니다 .

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;

}

다른 방법 (현재 G1에서 25MB 여유 공간 표시) :

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

Linux의 메모리 관리 철학은 "사용 가능한 메모리는 메모리 낭비입니다"입니다.

다음 두 줄은 "Buffers"에 얼마나 많은 메모리가 있고 "Cached"에 얼마나 많은지를 보여줄 것이라고 가정합니다. 둘 사이에는 차이가 있지만 (그 차이가 무엇인지 묻지 마십시오.) 둘 다 대략 파일 데이터와 메타 데이터를 캐시하는 데 사용되는 메모리 양에 추가됩니다.

A far more useful guide to free memory on a Linux system is the free(1) command; on my desktop, it reports information like this:

$ free -m
             total       used       free     shared    buffers     cached
Mem:          5980       1055       4924          0         91        374
-/+ buffers/cache:        589       5391
Swap:         6347          0       6347

The +/- buffers/cache: line is the magic line, it reports that I've really got around 589 megs of actively required process memory, and around 5391 megs of 'free' memory, in the sense that the 91+374 megabytes of buffers/cached memory can be thrown away if the memory could be more profitably used elsewhere.

(My machine has been up for about three hours, doing nearly nothing but stackoverflow, which is why I have so much free memory.)

If Android doesn't ship with free(1), you can do the math yourself with the /proc/meminfo file; I just like the free(1) output format. :)


I refer few writings.

reference:

This getMemorySize() method is returned MemorySize that has total and free memory size.
I don't believe this code perfectly.
This code is testing on 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;
    }

I know that Pattern.compile() is expensive cost so You may move its code to class member.


I looked at Android Source Tree.

Inside com.android.server.am.ActivityManagerService.java (internal service exposed by android.app.ActivityManager).

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);
}

Inside android.os.Process.java

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

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

It calls JNI method from android_util_Process.cpp

Conclusion

MemoryInfo.availMem = MemFree + Cached in /proc/meminfo.

Notes

Total Memory is added in API level 16.


you can also use DDMS tool which is part of android SDK it self. it helps in getting memory allocations of java code and native c/c++ code as well.


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;
}

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

It is a strange code. It return MaxMemory - (totalMemory - freeMemory). If freeMemory equals 0, then the code will return MaxMemory - totalMemory, so it can more or equals 0. Why freeMemory not used?

참고URL : https://stackoverflow.com/questions/3170691/how-to-get-current-memory-usage-in-android

반응형