마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

실시간 여유 메모리 관리 (Thread, ActivityManager.MemoryInfo 관련)

0 추천
안녕하세요!

항상 많은 도움과 조언을 얻어가서 너무 감사드립니다.

현재 개발하는 어플에서 메모리가 넘쳐서 어플이 종료되는 문제가 있습니다.

3D 모델을 불러와서 가시화를 하는 도중에 native heap의 메모리를 너무 많이 소비하여 프로세스가 종료하는 문제입니다.

해당 문제에 대한 해결책을 적용하기 위하여 우선적으로 현재 디바이스(태블릿, RAM : 3GB)에서 사용할 수 있는 여유 heap을 체크할 수 있도록 Thread를 활용하여보았습니다.

해당 코드는 아래와 같습니다.

        Thread myThread = new Thread(new Runnable() {
                        public void run() {
                            while(true) {
                                ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
                                ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
                                manager.getMemoryInfo(info);

                                String availMem = StringUtil.getString(info.availMem / 1048576L);

                                Log.e("Memory", availMem);
                }
            }
        });

다만 문제점이 있습니다.

위의 코드는 현재 MainActivity.java 에 속해있으며, 메인 코드에서 myThread.start(); 명령을 통하여 어플 전체 오느곳에서나 Log를 통해 여유 메모리를 체크할 수 있는 상황입니다.

하지만, 해당 쓰레드가 실시간으로 돌아가기 때문에 과부하가 걸리고, 전체 프로세스에 악영향을 주고 있으며, 이를 완화하기 위하여 매 0.5초마다 로그를 찍는 방식으로 개선하려 하였습니다.

이를 위하여 Thread 의 while 문 마지막단에 Thread.Sleep(500); 을 걸러 과부하를 줄이려 하였습니다.

하지만 해당 Sleep 구문에 오류가 있는 상황입니다.

해결책을 알아보던 중 클래스를 따로 생성하여 sleep을 걸어보니 걸리는것을 확인하였지만, 그렇게 될 경우 반대로 ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 구문에서 getSystemService 함수를 사용할 수 없게 되었습니다.

결국 Sleep을 포기하던지 메모리 체크를 정확하게 할 수 없던지 양자택일의 상황에 처해있는데요,

혹시 이와같은 문제에 대하여 조언이 있으시다면 언제든지 부탁드리겠습니다!

감사합니다!
익명사용자 님이 2016년 9월 21일 질문
sleep 구문을 넣었는데 getSystemService 함수가 동작 자체를 안하는것인가요? 아니면 사용 할 수 없는 상황인건가요? 사용할 수 없는 상황이라면 왜 사용할 수 없는 상황인건지도 알려주시면 답변에 도움이 될거같습니다.
안녕하세요!
우선 위의 코드에서 로그 구문 위쪽에 sleep함수를 아래와 같이 넣어보았습니다.

                                Thread.sleep(500);
                                
                                Log.e("Memory", availMem);
이럴경우, Thread 구문에 붉은줄이 가며,unhandled exception: java.lang.interruptedException 이라는 오류가 발생합니다.

이와는 반대로 클래스로 생성하여 구현을 할 경우, getSystemService에 빨간줄이 생기고 Cannot Resolve method 'getSystemService(java.lang.String)' 이라고 오류가 생깁니다.
Handler로 postDelayed를 주셔도 될 것 같은데요.
그리고
ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
                                ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

부분은 루프 밖에 있는게 조금이라도 퍼포먼스에 도움이 될 것 같습니다.

1개의 답변

0 추천
sleep 함수는 기본적으로 interruptedException을 뱉어내기때문에 당연이 try ~ catch로 묶어 주셔야 하구요. getSystemService는 context의 멤버함수입니다. 별도 클래스에서 이 함수를 사용하시려면 생성자 파라미터로 context를 받아서 context.getSystemService 이런식으로 호출 하셔야 합니다.
Development Guy (69,670 포인트) 님이 2016년 9월 21일 답변
...