레이블이 엑티비티인 게시물을 표시합니다. 모든 게시물 표시
레이블이 엑티비티인 게시물을 표시합니다. 모든 게시물 표시

2017년 1월 13일 금요일

[안드로이드] Activity Leak 확인 툴 - LeakCanary

엑티비티 Leak

엑티비티의 참조가 남아있어서 Destroy 후에도 GC되지 않는 증상으로, 안드로이드에서 메모리 누수의 주 원인으로 꼽힌다. 엑티비티 인스턴스는 다른 인스턴스에 비해서 메모리를 많이 차지하고, 일반적으로 뷰 등 여러가지 멤버필드를 가지고있기 때문에 엑티비티 Leak이 발생하면 자칫 치명적인 성능저하를 유발할 수도 있다.

LeakCanary

Square 사(BetterKnife 만든 회사)에서 만든 무료 라이브러리로, 그나마 쉽게 엑티비티 Leak을 감지할 수 있도록 도와준다.

적용방법

  1. app의 build.gradle에 다음의 dependancy를 추가한다.
dependencies {
    //Debug용 컴파일
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
   //Release용 컴파일 - Release시에는 아무 동작도 안하도록
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
}
2.Application의 onCreate() 메서드에서 초기화한다.
public class ExampleApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    if (LeakCanary.isInAnalyzerProcess(this)) {
      // This process is dedicated to LeakCanary for heap analysis.
      // You should not init your app in this process.
      return;
    }
    LeakCanary.install(this);
    // 앱 초기화 로직
  }
}

이용방법

앱을 테스트하다보면 다음 이미지와 같이, 추가한적 없는 아이콘이 보이는 경우가 있는데, 저 아이콘이 보이고 Notification이 존재한다면 현재 앱은 엑티비티 Leak이 존재하는 것이다.
Notification을 클릭하면, 왜 Leak이 발생했는지를 보여주는 화면이 나타난다.

장/단점

  • 장점
    • 적용이 매우 쉽다.
    • Leak이 발생하면 시각적으로 알 수 있어서 직관적이다.
  • 단점
    • Activity Leak를 확인하는 것만 가능하다. - 다른 메모리 Leak은 불가능
    • Activity의 Destroy 시점에서 검사를 진행하므로 화면 전환속도가 조금 느리다. - release 버전에서는 LeakCanary가 동작하지 않도록 빈 라이브러리를 컴파일하거나, 라이브러리를 제거해야 한다.

참고자료

2016년 12월 16일 금요일

[안드로이드] Process와 Task 차이

안드로이드의 Process

타 운영체제와 마찬가지로, 실행가능한 프로그램 데이터가 메모리로 로드되어 실행된 것을 프로세스라고 한다. 안드로이드는 리눅스 기반의 OS이므로, 리눅스의 프로세스처럼 각각 ID가 부여되며, 다른 프로세스와 철저히 격리되어 실행된다.

Process의 구등

안드로이드는 앱의 컴포넌트(엑티비티, 서비스, 리시버, 프로바이더)를 실행하는 시점에서, 그 컴포넌트가 메모리로 로드되고, 컴포넌트가 속한 앱의 프로세스가 구동된다.
Note : 앱의 프로세스가 새로 구동될 때마다, 시작점은 Application의 onCreate()메서드이다.

Process 변경

컴포넌트는 기본적으로 앱의 프로세스에 속하지만, 소속 프로세스를 변경할 수도 있다.
메니페스트 파일에서 컴포넌트를 선언할 때, android:process 필드를 지정하면, 이 컴포넌트는 앱의 프로세스와는 별개로, 다른 독립된 프로세스에서 실행된다.
Note : 별도의 프로세스에서 동작하더라도, Application의 onCreate()메서드는 호출된다.(왜그럴까......??)

안드로이드의 Task

앱을 실행하게 되면, 그 앱은 필요한 컴포넌트들을 호출하게 된다. 각 앱마다 현재 사용하고 있는 컴포넌트들을 그룹화하여 관리하는 것이 Task이다. 여기서의 컴포넌트는 해당 앱에 속한 컴포넌트 일수도 있고, 다른 앱에 속한 컴포넌트 일수도 있다.

컴포넌트 교차 생성

안드로이드의 독특한 특징으로, 다른 앱에 속한 컴포넌트를 호출하여 사용할 수 있다. 이렇게 호출된 컴포넌트는 현재 실행되고 있는 앱의 Task에 속하게 된다. 하지만, 호출된 컴포넌트가 메모리에 로드되면, 그 컴포넌트의 원래 프로세스가 구동되며, 컴포넌트가 실행되면서 필요한 권한설정은 원래 앱이 획득한 권한설정을 따르게 된다.
  • ex) 메모앱에서 기본 카메라의 엑티비티를 호출하는 경우
    • 기본 카메라의 엑티비티는 메모앱의 Task로 묶이게 된다.
    • 메모앱이 기본 카메라 엑티비티를 호출하는 시점에, 기본 카메라 앱의 프로세스가 구동된다. 즉, 메모앱의 프로세스와 기본 카메라 앱의 프로세스가 동시에 실행중인 상황이 된다.
    • 기본 카메라 엑티비티가 사용하고자 하는 권한(카메라 접근, 외부저장소 저장 등)은 메모앱의 권한설정이 아닌, 기본 카메라 앱의 권한설정을 따르게 된다. 따라서, 메모앱은 사진관련 권한이 없어도, 기본 카메라 앱에 권한이 있으면 문제없이 이용할 수 있고 반대로, 메모앱이 사진관련 권한이 있어도, 기본 카메라 앱에 권한이 없으면 기능을 이용할 수 없다.

엑티비티 스택

Task는 엑티비티의 순서를 관리하기 위해 별도로 스택을 유지하여 엑티비티를 저장한다. 즉, Task가 지워지면, 엑티비티의 순서도 지워지게 된다.

Task 변경

다른 컴포넌트들에 비해, 엑티비티는 메니페스트에서 <activity>태그의 android:launchMode 필드를 주거나, 엑티비티를 실행할 인텐트에 플래그 값을 추가하여 Task를 변경할 수 있다.(변경이라고는 해도 Task간 이동은 불가능하다.)