2012-06-20 3 views
4

내 안드로이드 애플 리케이션은 시간이 지남에 따라 점점 더 많은 메모리를 사용하고 있습니다. 나는 힙 덤프를 가져 와서 그것을 MAT로 분석했다. 내 안드로이드 애플 리케이션은 너무 많은 메모리를 소비합니다

그래서 (뒤로 버튼) 나 응용 프로그램을 종료 한 후에 메모리에서 지워지지 않습니다 내 활동을 한 것 같아 내가 응용 프로그램을 다시 시작할 때 다음 새로운 인스턴스가 생성됩니다

다음은 주요 누출 용의자 기억을 채 웁니다.

이제 PhantomReferences인데 잠시 ​​후에 또는 앱을 종료 할 때 메모리가 지워지지 않는 이유는 무엇입니까? 메모리는 다른 앱 등을 사용하는 경우에도 절대로 지워지지 않습니다. 앱을 완전히 닫는 유일한 방법은 작업 관리자를 사용하여 수동으로 앱을 종료하는 것입니다.

무정부 상태의 메모리 소비를 방지하려면 어떻게해야합니까?

편집 :

문제점을 발견했습니다! 각 액티비티는 Thread.setDefaultUncaughtExceptionHandler()로 CustomExceptionHandler를 설정하고 있으며 CustomExceptionHandler가 컨텍스트에 대한 참조를 유지하고 있다고 생각했습니다. 그래서 컨텍스트 레퍼런스를 없애고 onDestroy() 메서드에서 DefaultUncaughtExceptionHandler를 null로 만들었습니다. 그게 정말 나아!

+0

스레드, Asyntasks가 있습니까? – Jonas

+0

예 실제로 모두 – Alexis

+1

... 그들을 죽입니까? – Jonas

답변

5

매트의 도미노 트리 기능을 사용하여 위 참조가 무엇인지 알아 냈습니다. 이것이 Activity이 범인이라는 아이디어를 줄 수 있습니다.

어디서나 Context을 전달하지 않았는지 확인하고 참조를 보관하십시오. 이것은 고전적인 안드로이드 메모리 누출이며 정말 쉽게 할 수 있습니다! 일부 정적 분석 도구는 당신의 Activity 당신이 가끔 가비지 컬렉터를 조금씩 이동하는 (프리미티브 제외) null 모든 로컬 변수를하는 데 도움이 할 수 있고 쉽게 분석 할 수있는 힙 덤프 할 수의 onDestroy() 방법으로, 이것에 싫은 내색을하지만

MAT에서.

+0

로컬 변수는 메서드가 종료 될 때 스택에서 자동으로 제거됩니다.onDestroy() 메서드에서 인스턴스 변수가 null로 표시되어야한다는 의미입니까? 나는 약간 불분명하다. – Manpreet

5

일부 일반적인 접근 방식은 제가 일반적으로 수행하는 것은이되는 응용 프로그램의 크기를 줄이기 위해 : 다음 활동에 텐트를 전달 아래

  • 통화 종료()이 스택의 최대 말뚝 박기 방지하고 (GC에 도움 가비지 컬렉션)
  • 경우, 데이터를 저장하는 System.exit를 호출하여 출구를 플러시 공유 환경 설정을 사용하지 않는()
  • 당신은 당신이 사용하지 않는 당김 이미지/레이아웃 XMLS이/자바 클래스를 찾을 경우 최종 프로그램, 프로젝트에서 제거하십시오.
  • JPEG 이미지는 많은 메모리를 사용하기 때문에 이미지는 .png이어야합니다.
  • 데이터베이스 (sqlite, 내부 데이터베이스 등)를 사용하는 경우 더 나은 접근 방법은 "try/catch/finally"블록을 사용하는 것입니다. 데이터베이스를 열어 마지막으로 닫으면 메모리 누수가 발생하지 않습니다 커서 나 데이터베이스를 닫지 않기 때문입니다.
  • 스레드 대신 AsyncTask를 사용하십시오. onPostExecute() 함수에서 진행 대화 상자를 닫습니다.
관련 문제