안 드 로 이 드 사용 Handler 메모리 유출 분석 및 해결 방법
자 바 는 메모리 에 있 는 대상 을 GC 를 통 해 자동 으로 검사 하고(가상 컴퓨터 에 의 해 언제 검사 할 지 결정)GC 에서 한 개 또는 한 그룹의 대상 이 도달 할 수 없 는 상태 인 것 을 발견 하면 이 대상 을 메모리 에서 회수 합 니 다.즉,한 대상 이 어떠한 인용 에 도 가리 키 지 않 으 면 해당 대상 은 GC 에 발 견 될 때 회수 된다.또한 한 그룹의 대상 에 서로 인용 만 포함 되 어 있 고 외부 에서 인용 되 지 않 는 다 면(예 를 들 어 두 개의 대상 A 와 B 가 서로 인용 을 가지 고 있 지만 외부 대상 이 A 나 B 를 가리 키 는 인용 을 가지 고 있 지 않 음)이 는 여전히 도착 할 수 없고 GC 에 의 해 회수 된다.
Android 에서 Handler 를 사용 하여 메모리 유출 의 원인
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
handler 를 자주 사용 할 때 위 와 같이 정 의 됩 니 다.그러나 AS 의 lint 검 측 은 자동 으로 오류 경고 알림 을 보 냅 니 다.다음 그림 입 니 다.위 에는 간단 한 Handler 의 사용 이 있다.내부 클래스(익명 클래스 포함)를 사용 하여 Handler 를 만 들 때 Handler 대상 은 외부 클래스(보통 Activity)의 인용 을 암시 적 으로 가지 고 있 습 니 다(그렇지 않 으 면 Handler 를 통 해 Activity 중의 View 를 어떻게 조작 할 수 있 습 니까?).한편,Handler 는 보통 시간 이 걸 리 는 배경 스 레 드(예 를 들 어 네트워크 에서 그림 을 끌 어 올 리 는 것)와 함께 나타 납 니 다.이 배경 스 레 드 는 작업 수행 이 끝 난 후에 메시지 체 제 를 통 해 Handler 에 게 알 린 다음 에 Handler 는 그림 을 인터페이스 로 업데이트 합 니 다.그러나 사용자 가 네트워크 요청 과정 에서 Activity 를 닫 았 다 면 정상 적 인 상황 에서 Activity 가 더 이상 사용 되 지 않 으 면 GC 검사 에서 회수 되 었 을 수 있 습 니 다.그러나 이때 스 레 드 가 완료 되 지 않 았 기 때문에 이 스 레 드 는 Handler 의 인용 을 가지 고 있 습 니 다(그렇지 않 으 면 Handler 에 게 어떻게 메 시 지 를 보 냅 니까?).이 Handler 는 Activity 의 인용 을 가지 고 있 기 때문에 이 Activity 는 네트워크 요청 이 끝 날 때 까지 회수 할 수 없습니다(예 를 들 어 이미지 다운로드 가 끝 날 때 까지).또한 Handler 의 postDelayed()방법 을 실행 하면 이 방법 은 Handler 를 Message 에 불 러 오고 이 Message 를 Message Queue 에 밀어 넣 습 니 다.설정 한 delay 가 도착 하기 전에 Message Queue->Message->Handler->Activity 의 체인 이 있어 Activity 가 인용 되 어 회수 되 지 않 습 니 다.
2.메모리 유출 의 위해
메모리 유출 의 위 해 는 가상 컴퓨터 가 메모 리 를 너무 많이 차지 하여 OOM(메모리 넘 침)을 초래 하고 프로그램 이 잘못 되 는 것 이다.
안 드 로 이 드 애플 리 케 이 션 에 있어 서 사용자 가 Activity 를 열 고 사용 한 후에 닫 으 면 메모리 가 새 는 것 입 니 다.열 고 닫 고 새 고;몇 번 후에 프로그램 이 메모 리 를 차지 하 는 것 은 시스템 제한,FC 를 초과 했다.
3.해결 방안
Handler 를 사용 하여 메모리 유출 을 야기 하 는 해결 방법
방법 1(공식 해결 방법):
private Handler mHandler2 = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
//do something
return false;
}
});
방법 2:프로그램 논 리 를 통 해 보호 한다.1.Activity 를 닫 을 때 배경 스 레 드 를 멈 춥 니 다.스 레 드 가 멈 추 면 핸들 러 와 외부 로 연 결 된 선 을 끊 은 셈 이 고,액 티 비 티 는 자 연 스 럽 게 적절 한 시점 에 회수 된다.
2.만약 당신 의 Handler 가 delay 의 Message 에 의 해 인용 되 었 다 면,해당 Handler 의 removeCallbacks()방법 을 사용 하여 메시지 대상 을 메시지 대기 열 에서 제거 하면 됩 니 다.
방법 3:Handler 를 정적 클래스 로 설명 합 니 다.
PS:자바 에 서 는 비정 상 내부 클래스 와 익명 내부 클래스 가 외부 클래스 의 인용 을 암시 적 으로 가지 고 있 으 며,정적 내부 클래스 는 외부 클래스 의 인용 을 가지 고 있 지 않 습 니 다.
정적 클래스 는 외부 클래스 의 대상 을 가지 고 있 지 않 기 때문에 Activity 는 마음대로 회수 할 수 있 습 니 다.Handler 는 외부 클래스 대상 의 인용 을 더 이상 가지 고 있 지 않 기 때문에 Handler 에서 Activity 의 대상 을 조작 하 는 것 을 허용 하지 않 습 니 다.그래서 Handler 에 Activity 에 대한 약 한 인용(Weak Reference)을 추가 해 야 합 니 다.
코드 는 다음 과 같 습 니 다:
static class MyHandler extends Handler {
WeakReference<Activity> mWeakReference;
public MyHandler(Activity activity) {
mWeakReference = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
final Activity activity = mWeakReference.get();
if (activity != null) {
if (msg.what == 1) {
activity.noteBookAdapter.notifyDataSetChanged();
}
}
}
}
어떤 방법 이 든 현재 인터페이스 성명 주기 가 끝 난 후에 handler 대기 열 에 있 는 메 시 지 를 제거 하 는 것 을 기억 하 십시오.
handler.removeCallbacksAndMessages(null);
PS:Weak Reference 가 무엇 입 니까?Weak Reference 의 약 한 인용 은 강 한 인용(즉,우리 가 흔히 말 하 는 인용)과 상대 적 으로 GC 가 회수 할 때 약 한 인용 을 무시 하 는 것 이 특징 입 니 다.즉,약 한 인용 이 특정한 대상 을 가리 키 더 라 도 이 대상 이 강 한 인용 방향 으로 가리 키 지 않 는 다 면(실제로 대부분 부 드 러 운 인용 이 없 으 라 고 요구 하지만 여기 서 부 드 러 운 인용 개념 은 무시 할 수 있 습 니 다).그 대상 은 GC 검 사 를 받 을 때 회수 할 것 이다.위의 코드 에 대해 사용 자 는 Activity 를 닫 은 후에 백 스테이지 스 레 드 가 끝나 지 않 았 더 라 도 Handler 에서 온 약 한 인용 이 Activity 를 가리 키 기 때문에 GC 는 검사 할 때 Activity 를 회수 합 니 다.이렇게 하면 메모리 유출 문제 가 발생 하지 않 을 것 이다.
총화
안 드 로 이 드 의 많은 메모리 유출 은 Activity 에서 비 정적 내부 류 를 사 용 했 기 때문에 발생 한 것 입 니 다.우 리 는 비 정적 내부 류 를 사용 할 때 반드시 주의해 야 합 니 다.만약 에 이 정적 내부 류 의 인 스 턴 스 대상 의 생명 주기 가 외부 대상 보다 크 면 내부 저장 유출 을 초래 할 수 있 습 니 다.위 에서 소개 한 정적 류 와 약 한 인용 방법 으로 이런 문 제 를 해결 하 는 것 을 추천 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.