고성능의 안드로이드 개발 (메모리 최적화)


그림 삽입 설명 여기
메모리 문제 : 이상 (OOM 메모리 할당 실패 등) Caton의
향상된 양방향 :

RAM의 최적화

그 감소 된 런타임 메모리. OOM 프로그램은 메모리 LMK기구를 살해하기에 너무 크기 때문에, 프로그램의 가능성을 줄일뿐만 아니라, 예외의 발생을 방지 할 수있다.

최적화 ROM

즉, 프로그램 ROM의 볼륨 감소. 여기 인해 공간 리드 ROM의 부족으로 설치할 수 없습니다 방지하기 위해 프로그램이 차지하는 공간을 줄이기 위해 주로이다.

모바일 기기의 개발

장비 성능 평가 :
모바일 기기가 페이스 북이라는 장치 년 수준의 오픈 소스 라이브러리를 개발했다.

2008 140메가바이트 RAM, 2,018 메이트 (20) 프로 8기가바이트 RAM.
그림 삽입 설명 여기

신화 : 기본 메모리 제어를하지 않습니다

기본 메모리의 물리적 메모리가 부족, LMK는 프로세스를 종료하기 시작했다.
예 : 비트 맵 수동으로 기본 힙에 할당 발표했다.

// 步骤一:申请一张空的 Native Bitmap
Bitmap nativeBitmap = nativeCreateBitmap(dstWidth, dstHeight, nativeConfig, 22);

// 步骤二:申请一张普通的 Java Bitmap
Bitmap srcBitmap = BitmapFactory.decodeResource(res, id);

// 步骤三:使用 Java Bitmap 将内容绘制到 Native Bitmap 中
mNativeCanvas.setBitmap(nativeBitmap);
mNativeCanvas.drawBitmap(srcBitmap, mSrcRect, mDstRect, mPaint);

// 步骤四:释放 Java Bitmap 内存
srcBitmap.recycle();
srcBitmap = null;

메모리 누수 탐지 및 수정

메모리 누수

A.의 메모리 누수 모니터링 프로그램

방법 1 : leakcanry

그것은 발견 메모리 누수가 자동으로 HPROF 파일을 덤프 경우, HAHA 라이브러리에 의해 최단 경로 공개를 얻을, 그리고 마지막으로 통지 쇼를 통해, 약한 참조 객체에 의해 활동 또는 조사를 라이프 사이클.

  • dumphprof 여전히 응용 프로그램 명백한 Caton (SuspendAll 스레드) 원인.

leakcanry 간단한 맞춤을 수행함으로써, 메모리 누출 모니터링 다음 폐 루프를 달성 할 수있다.
그림 삽입 설명 여기

방법 2 : DDMS

안드로이드 스튜디오 후 3.0 개방 DDMS 구글은 DDMS를 포기하지 않을 수 있습니다

  • 안드로이드 SDK / 도구 /의 SDK에서이 monitor.bat 배치 파일 [경로 및 구성 ADB 명령 같은 경로입니다]
    그림 삽입 설명 여기

1, 당신은 디버깅 과정에서 업데이트 힙 클릭해야

2, 힙을 사용하여 도로의 오른쪽을 클릭, 원인 GC 클릭 상황은 실시간으로 메모리에서 볼 수 있습니다

방법 세 가지 명령 행

ADB 쉘 dumpsys meminfo 파일 <PACKAGE_NAME | PID> [-d]

ADB 해당 PID 또는 패키지 이름을 찾습니다 PS 쉘
그림 삽입 설명 여기

방법 사 : 할당 추적기

  • 정보의 파편
  • Traceview으로, 자동화 된 분석 할 수없는 것처럼, 수동으로 각 끝을 시작합니다.
  • 할당 시간을 추적하고이 데이터 덤프 때까지 정지, 심지어 일반 휴대 전화 ANR을 부착하기 전에 전화 자체의 성능에 너무 많은 영향을 야기하지만,하지 않습니다.

방법 오 : 안드로이드 스튜디오 프로파일

II는. 시스템 메모리 해킹 수정 누수

시스템이 추천에 의해 해킹을 해결하는 방법에 대한 권장 사항을 제공 할 것입니다, 예제의 대부분을 동시에 출시 할 수 없기 때문에 AndroidExcludedRefs 목록은 몇 가지 이유는 예를 들었다. ,,, 마이크로 편지

메모리의 대체 복구 채용

활동 누출 메모리 압력의 결과로, 비트 맵, DrawingCache로 활동 참조를 일으키는 등 해제 할 수 없습니다, 세부 활동 누출 된 모든이가 보유하고있는 자원 만 누출 활동 쉘 복구를 시도 계시 재활용하기위한 수단하여 메모리에 대한 압력을 감소시킨다.

연습도 매우 간단하고, 자원 쉘을 고려하지 않는 작업이되고, 배경, DrawingCache, 청취자 등 자원 순환 릴리스의 rootview보기 활동 onDestory 시간에 관련된 모든 아이 뷰의 이미지에서 시작, 그것은 누출되지 않습니다 사진 원인 자원을 개최한다.

  Drawable d = iv.getDrawable();
  if (d != null) {
      d.setCallback(null);
  }        
  iv.setImageDrawable(null);

전반적으로, 우리는 몇 가지 메모리 솔루션은 폐쇄 루프 시스템의 집합의 메모리 누수 탐지 및 수정을 얻기 위해, 더 중요한 것은, 일상적인 테스트 및 모니터링을 통해 할 수있다 누수 방법을 모른다.

런타임 메모리를 줄이는 몇 가지 방법

우리는 응용 프로그램이 메모리 누수에 표시되지 않도록 할 때, 우리는 런타임 메모리를 줄일 수있는 다른 방법이 필요합니다. 더 자주, 우리는 정말로 유일한 OOM 응용 프로그램의 발생 확률을 줄이고 자.

A. 비트 맵 메모리 사용량을 줄이고

다음 장을 참조하십시오

II. 자신의 메모리 모니터

전체 시스템의 시스템 기능 onLowMemory과 다른 기능,이 프로세스에 해당 달빅 메모리 OOM의 차이가 반영되지 않으며, 분리 메모리 우리 콜백 함수에 대한 시간이다.

  • 프로세스 힙 메모리 사용량 실시간 모니터링 모듈이 출시 관련 메모리를 알리기에 관한 설정 값에 도달 :
Runtime.getRuntime().maxMemory();  
  Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()
  • 작동 모드
    우리는 위험한 수준 (예 : 80 %)에 도달 할 때 정기적으로 (3 분마다 전경)에는,이 값을이 값을 얻기 위해, 우리는 주로 (캐시의 대부분을위한 비트 맵) 우리의 다양한 캐시 자원을 해제해야합니다.
WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE)

III. 파렴치한 사용 개방 과정이 있습니다

각각의 빈 프로세스는 10MB의 소모합니다.
웹보기, 갤러리 등으로 인해 메모리 누수 또는 너무 많은 시스템 메모리 문제를 가지고, 우리는 별도의 프로세스를 채택 할 수있다. 현재 마이크로 채널은 별도의 프로세스 도구에 넣어 것입니다.

IV. 자세한보고 OOM

충돌 OOM 시스템은 메모리 정보를 발생합니다. 큰 힙, inBitmap, SparseArray. . .

GC 최적화

GC 성능 테스트

예를 일시 중단 시간의 경우, 총 시간, GC는 처리량, 우리는 ANR 로그 SIGQUIT 신호를 전송하여 얻을 수 있습니다.

adb shell kill -S QUIT PID
adb pull /data/anr/traces.txt

它包含一些 ANR 转储信息以及 GC 的详细性能信息:
sticky concurrent mark sweep paused:	Sum: 5.491ms 99% C.I. 1.464ms-2.133ms Avg: 1.830ms Max: 2.133ms     // GC 暂停时间

Total time spent in GC: 502.251ms     // GC 总耗时
Mean GC size throughput: 92MB/s       // GC 吞吐量
Mean GC object throughput: 1.54702e+06 objects/s 

A. 타입 GC

1.GC_FOR_ALLOC
힙 메모리 가능성이 트리거 될 수있는 충분한 시간이되지 않습니다 특히 새 개체. 시동시 GC_FOR_ALLOC의 개수가 감소 될 수 있도록 Dalvik.vm.heapstartsize 값이 증가 될 수있다. 이 트리거가 동기화 된 방식으로 수행되고 있습니다.

2.GC_EXPLICIT가
가비지 수집 프로세스는 반드시 즉시 트리거되지 않습니다 그래서 GC가 System.gc 같은, 호출 할 수 있습니다, 일반적인 GC 스레드의 우선 순위는 상대적으로 낮다.

3.GC_CONCURRENT
객체의 크기 분포가 트리거 될 때보다 384 K,이 비동기 방식의 재활용입니다. 당신의 큰 숫자를 발견하면 참고 동시 GC 시스템이 할당 384K 이상의 대상이되었을 수도 있지만,이 종종 있음을 나타내는 표시 반복 일부 임시 개체가 반복적으로 트리거됩니다. 우리에게주는 힌트는 다음과 같습니다 객체 재사용이 충분하지 않습니다.

4.GC_EXTERNAL_ALLOC (시스템 이후 3.0이 소요됩니다)

II. 메모리 지터

짧은 시간에 많은 수의 개체가 생성 즉시 해제됩니다.
이 작업은 프레임 율에 영향을 미칠 수 있으며, 그래서 사용자는 성능 문제를 인식.

세 가지. GC 최적화

1. 문자열 연결 최적화
의 StringBuilder를 사용하여 문자열 더하기 기호 바느질을 줄일 수 있습니다.
감소 StringBuilder.enlarge 제공 용량 초기화;

logging.println(">>>>> Dispatching to " + msg.target + " " +
                msg.callback + ": " + msg.what);

최적화 2. 읽기 파일을 파일을 읽을 ByteArrayPool, 초기 설정 용량, 확장 줄일 수 있습니다.

3. 자원 재사용
빈번한 전역 애플리케이션 버퍼 풀 재사용 개체 자료 형식

4. 불필요하거나 비합리적인 개체 감소
된 onDraw 예를 삭감의 getView 타겟 애플리케이션 재사용하려고한다. 무언가의 이상이 로컬 변수, 예를 들면, 연속적으로 순환 응용 등 논리적

적절한 데이터 포맷 SparseArray, SparseBooleanArray 및 LongSparseArray 대신 해시 맵의 선택

좋은 최적화 목표를 설정 :
예를 들어 512MB의 2GB의 장비 이상의 장비가, 두 개의 완전히 다른 최적화 아이디어이다.
동남 아시아, 아프리카, 사용자의 경우, 표준 메모리 최적화는 일부의 요구 이상이 될 것이라고.

메모리 최적화 3 양태

장비 분류, 비트 맵 메모리 누수 이러한 세 가지 측면을 최적화.

1 등급 장비

유사한 장치 년 급 저급 기계 등 (565) 형식의 포토, 적은 캐시를 이용하여, 복잡한 애니메이션 또는 일부 기능을 닫았다.

if (year >= 2013) {
    // Do advanced animation
} else if (year >= 2010) {
    // Do simple animation
} else {
    // Phone too slow, don't do any animations
}
  • 캐시 관리
    캐시를 통합. 시스템 메모리가 부족하면, 메모리의 적시 출시.
  • 프로세스 모델
    빈 프로세스가 메모리 10MB의를 차지합니다. 증가 과정 악랄한.
  • 설치 패키지 크기
    그들과 좋은 관계의 메모리를 복용 코드, 자원, 그래서 그림 라이브러리의 볼륨.

2, 비트 맵 최적화

안드로이드 비트 맵의 ​​진화 분석 :

  • 달빅은 + 할당 안드로이드 2.X 시스템, 최대 외부 할당 + 새로 할당 된 크기> = 달빅 힙 OOM이 발생하면. 여기서, 비트 맵은 외부 매체에 배치된다.
    픽셀 데이터가 기본 메모리에 배치되는 동안 자바 힙에 비트 맵 객체. 당신이 재활용 호출하지 수동으로 할 경우, 비트 맵 기본 메모리 복구 전적으로 의존 마무리 콜백 함수는, 학생들은이 기회가 제어 할 수 없습니다 것을 알아야한다 자바 잘 알고 있습니다.
    안드로이드 2.x에서 시스템 BitmapFactory.Options이 반사 오프닝 inNativeAlloc 안에 숨겨져 후, 비트 맵은 외부의 응용 프로그램에서 계산되지 않습니다.

  • 안드로이드 3.0 ~ 안드로이드 7.0은 비트 맵 객체와 자바 힙에 픽셀 데이터를 통합합니다.
    우리는 재활용을 호출하지 않도록 경우에도, 비트 맵 메모리는 객체와 함께 복구됩니다.
    자바 힙 제한은 아마 내 실제 메모리뿐만 아니라 5기가바이트하지만, 단지 512메가바이트하기 때문에 응용 프로그램의 부족 또는 OOM. 자바 힙 메모리 리드의
    안드로이드 4.x의 시스템, 외부 카운터의 폐지, 자바 달빅의 변화와 유사한 비트 맵 배포 긴 +> = 달빅 힙 최대 시간 OOM가 발생 (통계적 규칙 예술 달빅 운영 환경 또는 일치) 할당 된 새로운 메모리의 할당으로 어플리케이션 힙,
    한국어 프레스코 라이브러리 자원을 사용할 수있는 그림에 넣을 수 네이티브한다.

  • 안드로이드 8.x의 자바 네이티브 힙 힙에서 이동
    이 실현을 메모리에 기본 비트 맵을 넣을 수 있습니다, 당신은 또한 퀵 릴리즈를 할 수 있으며, GC 메모리도 남용을 방지하기 위해 고려 될 수있을 때 동안 함께 객체? NativeAllocationRegistry는 일단 안드로이드 8.0 메모리의 기본 메커니즘이 원조 다시 사용하는 것입니다,이 세 가지 요구 사항을 충족 할 수 있습니다.
    안드로이드 8.0은 또한 그림 메모리를 줄이고 효율성을 렌더링 향상시킬 수있는 하드웨어 비트 맵 하드웨어 비트 맵을 추가합니다.

구체적인 방법 :

1. 통일 갤러리

예 : 로우 엔드 기계 565 형식을 사용합니다. 당신은 글라이드, 프레스코를 사용하거나 할 수 있습니다 자기 개발을 할 수 있습니다. 그리고 Bitmap.createBitmap을 촉진 할 필요가 BitmapFactory 관련 인터페이스도 함께 수집합니다.

2. 통합 모니터링

비트 맵의 ​​사용을 모니터링하는 매우 쉬운 통일 후 갤러리에서, 여기에서주의해야 할 세 가지가있다.

  • 큰 그림을 모니터링. 넓은 방지합니다. 픽셀 폐기물
    즉 화상 사이즈 뷰의 사이즈를 초과해서는 안된다. 이와 관련, 우리는 이미지 뷰와 당김 대체 할 수 있습니다.
    현재 이미지 픽셀 폐기물, 0.9지도의 합리적인 사용을
  • 모니터링 복제합니다.
    답글 : 중복 비트 맵 분석은 백그라운드 서버에서 수행되는 지금 방법의 말을 바로에게 모든 비트 맵 배열에 대한 직접 계산 해시입니다.
  • 총 메모리의 사진.
    OOM의 충돌, 또한 총 메모리의 사진을 걸릴 수 있습니다 때, 상위 N 사진 메모리는 우리가 문제를 해결하는 데 도움이 충돌 로그에 기록됩니다.

좋은 공정에서는 imageLoader는, 2.X, 4.X 5.X 화상 또는 사용자는 숨겨진로드 할뿐만 아니라, 상기 프레임에 배치 적응성 크기, 품질 등이 될 수있다.

3 메모리 누수

메모리 누수는 단순히 사용되지 않는 메모리를 회수하지 않습니다.

: 메모리 누수는 두 가지 유형으로 나누어
동일한 개체 누수.
때마다 새로운 객체를 누출, 쓸모없는 객체의 수십만가 발생할 수 있습니다.

뛰어난 프레임 디자인은 줄일 수 있습니다 또는 피하기 프로그래머는 실수를합니다. 많은 메모리 누수가 부당 디자인 프레임 워크에 의해 발생, 수명주기의 모든 곳에서 하나의 경우 다양한 MVC 컨트롤러는보기보다 훨씬 더 크다.

  • 자바 메모리 누수는
    프로그램을 모니터링 자동화 유사한 LeakCanary을 설정합니다.
    개발하는 동안, 우리는 개발자가보다 쉽게 문제를 식별하고 해결할 수 있도록 팝업 대화 상자가 나타납니다 누출 바랍니다.
  • OOM 모니터
    US 기는 OOM의 경우, 별도의 프로세스를 통해이 문서의 더 다음 분석 HPROF 메모리 스냅 샷을 생성하여 메모리 누수 안드로이드 자동 링크 분석 성분 프로브를 갖는다. 그러나 온라인으로 추가 분석을 위해이 파일을 사용합니다. 그러나,이 온라인 도구 위험을 사용하여 비교적 큰, 충돌의 시간에 메모리 스냅 샷은 차 붕괴를 일으킬 수 있으며, 일부 휴대 전화 사용자에 대한이의 충격을 경험하는 데 몇 분 정도 걸릴 수 있습니다 HPROF 스냅 샷이 비교적 큰 생성합니다.
  • 모니터링 기본 메모리 누수
    내가 malloc에이 (malloc에 디버그) 디버깅과의 malloc 후크 (malloc에 후크가)는 상당히 안정적인 듯 이야기를. "안드로이드 단말기 메모리 최적화 연습 마이크로 편지"WeMobileDev 최근 기사에서, 마이크로 편지도 시도 위의 다른 프로그램을했다. https://mp.weixin.qq.com/s/KtGfi5th-4YHOZsEmTOsjg?
    너무 완벽하지 않습니다.

개발 과정과 함께, 시스템에 키를 매일 모니터링에 사용 문제 해결 메모리 누수 및 MAT Androd 프로파일 러 도구에 문제가 그래서 적시에 감지 기능을 사용할 수 있습니다.

메모리 모니터
, 일부 성능 모니터링 메모리 누수 문제를 보통 내부 직원 및 사용자의 아주 작은 부분을 엽니 다.
온라인 : 다른,보다 효과적인 방법으로 메모리 관련 문제를 모니터링 할 필요가있다.

취득 모드
사용자 샘플링이 아닌 유료 샘플에 따라한다. 사용자 수집 안타를 계속합니다.
사용자는 프론트 데스크에서, 당신은 매 5 분 PSS, 자바 힙, 사진 전체 메모리를 캡처 할 수 있습니다.

인덱스를 계산

메모리 UV 비정상적인 비율은 = PSS 이상 4백메가바이트 UV의 / UV 획득
PSS의이 PSS Debug.MemoryInfo에 의해 Debug.MemoryInfo 값을 얻을 수 있습니다 얻을 수있는 값입니다.
최고 속도를 터치 : 최대 힙 한도의 85 % 이상이, GC 가능성이 원인 OOM 및 Caton에 더 자주 될 것입니다 경우 자바는 메모리의 사용을 반영 할 수있다.

内存 UV 触顶率 = Java 堆占用超过最大堆限制的 85% 的 UV / 采集 UV

long javaMax = runtime.maxMemory();
long javaTotal = runtime.totalMemory();
long javaUsed = javaTotal - runtime.freeMemory();
// Java 内存使用超过最大限制的 85%
float proportion = (float) javaUsed / javaMax;

일반 고객은 당신이 유연 할 수 있도록 모든 계산은 백그라운드에서 처리되는 데이터를보고했다.

모니터링 3.GC
실험실 또는 내부 시험 환경에서, 우리는 또한도 사용할 수 있지만,이 옵션이 성능에 어떤 영향을 참고로 Debug.startAllocCounting에 의해 상황 자바 메모리 할당 및 GC를 모니터링 할 수 있지만,있다 사용되지 않는 안드로이드가 표시됩니다. 정보를 모니터링함으로써, 우리는 수와 메모리 할당의 크기, GC가 시작 횟수를 얻을 수 있습니다.

long allocCount = Debug.getGlobalAllocCount();
long allocSize = Debug.getGlobalAllocSize();
long gcCount = Debug.getGlobalGcInvocationCount();

안드로이드 6.0 시스템 후 GC에 대한 더 정확한 정보를 얻을 수 있습니다.

// 运行的 GC 次数
Debug.getRuntimeStat("art.gc.gc-count");
// GC 使用的总耗时,单位是毫秒
Debug.getRuntimeStat("art.gc.gc-time");
// 阻塞式 GC 的次数
Debug.getRuntimeStat("art.gc.blocking-gc-count");
// 阻塞式 GC 的总耗时
Debug.getRuntimeStat("art.gc.blocking-gc-time");

이 Caton을 발생하도록 응용 프로그램을 일으킬 수 있습니다 응용 프로그램 스레드를 중단하기 때문에 우리는 GC 차단 시간이 많이 소요의 수에 특히주의해야합니다.

게시 13 개 원래 기사 · 원 찬양 2 · 조회수 7,383

추천

출처blog.csdn.net/qq_37165429/article/details/104820032