Androidパフォーマンス最適化5-メモリ最適化


一、説明
Java仮想マシンは自動ゴミ回収メカニズムがあり、AndroidシステムのメモリーゴミもGCで自動回収されるので、開発者は普段Androidのメモリー管理にあまり関心を持たず、より多くの精力を業務に置くことができます.しかし、システム全体のメモリ制御の必要性のために、AndroidシステムはアプリケーションごとにハードなDalvik Heap Size最大制限閾値(この閾値はデバイスによってRAMの大きさによって異なる)を設定し、アプリケーションがメモリ領域を占有してこの閾値に近づいたり超えたりした場合、エラー(OOM)やパフォーマンスの問題が発生します.メモリの最適化は特に重要です.
二、メモリ不足による問題
1、カートン
まず、JavaはCやC++のように開発者が自分でメモリを解放する必要はありません.Androidでは、申請も解放もシステム層が負担します.
アプリケーションは使用中にメモリが増加するにつれて、一定の条件に達すると、GCはメモリの解放を開始し、GC中にはUIスレッドを含む他の作業中のスレッドは一時停止します.一般的に、このような解放操作が増加する時間は、アプリケーションの使用に影響を与えません.このような繰り返し操作が多くなると、他の作業時間が圧縮され、アプリケーションのレンダリング作業に影響を与えます.
例えば、短期間で大量のオブジェクトを申請するが、釈放されることは少ない.制限しきい値に近づくと、ゴミ回収アクティビティが開始され、メモリ申請が小さくてもアプリケーションのスタックメモリに圧力がかかり、ゴミ回収が開始されます.GCが頻繁であれば結構時間がかかり、カートンになりやすいです.
2、OOM
OOMのフルネームはOut Of Memory、すなわちメモリオーバーフローであり、実際に使用したメモリが最大制限値を超えたためにエラーが報告される.OOMの主な原因は次のとおりです.
  • 申請のスペースが大きすぎて、残りの割り当て可能なメモリを超えています.
  • メモリはある段階のピークがメモリ空間の閾値に達し、ちょうどこのピークの時、大きなメモリを申請する必要があり、スタックメモリ空間が不足してOOM異常を引き起こす.

  • 3、生存率に影響する
    OOMとUIカートンの原因に加えて、アプリケーションのバックグラウンドで実行される場合、特にサービスプロセスは、一連の方法でプロセスの優先度を高めても、メモリの消費量が高すぎると、システムリソースが緊張している場合でも、システムkillによって削除されます.
    五、メモリ漏れによる性能問題
    メモリ漏洩は全体的には役に立たない本来の解放回収の対象であるが,GCが回収できないためメモリ漏洩が発生し,漏洩が多くなり,利用可能なメモリ容量が少なくなると問題が発生する.
    詳細については、「Androidパフォーマンスの最適化3-メモリ漏洩の解決」を参照してください.
    六、メモリの最適化
    1、対象引用を合理的に利用する
    Javaでの引用は強引用、ソフト引用、弱引用、虚引用に分けられ、これらの引用タイプを合理的に利用することでGCのより合理的な回収を助けることができる.
    2、AutoBoxing
    説明:自動梱包の核心は、基礎データ型を対応する複雑なタイプに変換することであり、開発者自身が変換する必要はありません.目的:
  • これらの基礎データ型をほとんどのJavaコンテナで動作させるために、汎用では基本型は汎用パラメータを作ることはできません.
  • は、1つの基本タイプを1つのクラスにパッケージし、このタイプに多くの呼び出し可能な方法を持たせることができる.
  • //    
    List list = new ArrayList ()
    
    //   
    List list = new ArrayList ();
    

    例:
    Integer total = 0;
    for(int i = 0; i < 100; i++) {
    	total += i;
    }
    

    これにより、仮想マシンをループするたびに新しい整数オブジェクトを作成するパフォーマンスが向上します.基本データ型intは4バイトしか占めていませんが、Integerオブジェクトは16バイトなので、メモリと時間のパフォーマンスに追加のオーバーヘッドがあります.
    不要なメモリのオーバーヘッドなどの問題は、問題を少なくしないように、早期に発見する必要があります.一般に、多くのintegerが呼び出されていることが判明した場合、TraceViewまたはMemory Profilerで時間のかかる表示を行うことができる.valueは、AutoBoxingが発生したことを示し、コードをすぐに最適化する必要があります.
    3、メモリ多重化
    Androidシステムでは、一部のデータが多重化され、開発中にシステムが利用可能なインタフェースや方法を提供しています.たとえば、次の3つの多重化シーンでは、メモリ多重化によりアプリケーションのメモリオーバーヘッドを効果的に削減できます.
  • システムが持つリソースを有効に利用する:アプリケーションシステム自体に内蔵されたリソース、例えばいくつかの共通の文字列、色、共通のIcon、アニメーションスタイルと簡単なレイアウトはある程度メモリのオーバーヘッドを減らすことができて、またアプリケーション自身の負荷を減らすことができて、APKの大きさを減らして、しかも多重性はもっと良いです.
  • ビュー多重化:重複するサブコンポーネントが多数存在する場合、ViewHolderを使用してConvertView多重化を実現できます.
  • オブジェクトプール:プログラムを設計するときに明示的にプログラムにオブジェクトプールを作成し、多重化ロジックを実現し、同じタイプのデータに対して同じメモリ空間を使用するか、システムフレームワークの既存の多重化特性を持つコンポーネントを利用してオブジェクトの重複作成を減少させ、メモリの割り当てと回収を減少させることができる.
  • Bitmapオブジェクトの多重化:BitmapのinBitmapの高度な特性を利用して、AndroidシステムのBitmapでの分配と解放効率を高め、メモリ多重化だけでなく、読み書き速度も向上した.このプロパティは、既に存在するメモリ領域にbitmapを格納する領域を申請することができる.

  • 4、列挙タイプ
    列挙タイプ(Enums)を使用して定数を定義すると、コードが読みやすくなり、安全になりますが、通常の定数定義よりもパフォーマンスが低下します.
    Androidシステムは、アプリケーションが起動すると、アプリケーションにメモリを個別に割り当てます.アプリケーションのdex code、Heap、および実行時のメモリ割り当ては、このメモリに含まれます.一方、列挙タイプを使用するdex sizeは、通常の定数で定義されたdex sizeの13倍以上(dex codeが増加しただけ)であり、実行時のメモリ割り当てでは、1つのenum値の宣言に少なくとも20 bytesが消費され、オブジェクト配列を計算するにはenum値への参照を維持する必要はありません.各列挙項目は静的変数として宣言され、割り当てられます.したがって,アプリケーションに含まれるコードやLibにenumが大量に使用されると,メモリの小さい携帯電話に無視できない影響を及ぼす.
    列挙の最大の利点はタイプセキュリティであるが、Androidプラットフォームでは列挙のメモリオーバーヘッドが直接定義定数の3倍以上であるため、Androidの公式ドキュメントも開発者に列挙タイプの使用をできるだけ避けるように注意し、同時に注釈の方式を提供してタイプセキュリティを検査し、現在int型とString型の2種類の注釈方式を提供している:IntDefとStringDef、コンパイル期間のタイプチェックを提供します.
    public class Test {
        public static final int LEVEL1 = 1;
        public static final int LEVEL2 = 2;
        
        void main() {
            aaa(LEVEL1);
        }
        
        void aaa(@TestInterface int level) { ... }
        
        @IntDef({LEVEL1, LEVEL2})
        @Retention(RetentionPolicy.SOURCE)
        public @interface TestInterface { ... }
    }
    

    列挙タイプのセキュリティは、以上の方法で代替できます.
    5、LruCache
    LruCacheはandroidにいます.utilパッケージの下(android-support-v 4のパッケージで提供)は、最近最もキャッシュを使用していないように翻訳できます.キャッシュが必要なオブジェクトを強い参照で保存し、内部でキューを維持します(実際にはLinkedHashMap内部の双方向チェーンテーブルであり、スレッドセキュリティはサポートされていません.LruCacheはそれをカプセル化し、スレッドセキュリティ操作を追加しました).いずれかの値がアクセスされると、キューの末尾に配置され、キャッシュがいっぱいになると、キューヘッダの値(すなわち、最も最近アクセスされていない)が破棄され、その後、ゴミ回収されることができる.
    6、画像メモリの最適化
    Androidはプロセスごとに割り当てられる記憶領域が限られているため、画像はメモリ領域を大きく占有しているため、画像を合理的に最適化しなければ、メモリの過剰占有によって性能の問題を引き起こす可能性が高い.
    このブロックの内容が多いため、詳細については、Androidメモリ最適化4-ピクチャ最適化を参照してください.
    七、検査
    メモリの問題を検出するツールをいくつか紹介します.
  • Memory Profiler:メモリジッタを検出可能
  • LeakCanary:メモリ漏洩の検出
  • 六、まとめ
    全体的にメモリの最適化には、次のような意味があります.
  • はOOMを低減し、応用安定性を向上させる.
  • カートンを削減し、アプリケーションのスムーズさを向上させます.
  • メモリ消費量を削減し、アプリケーションのバックグラウンド実行時の生存率を向上させる.
  • 異常発生を減少させ、コード論理の危険性を減少させる.

  • 七、推薦
  • Androidパフォーマンス最適化1-起動最適化
  • Androidパフォーマンス最適化2-描画最適化
  • Androidパフォーマンスの最適化3-メモリ漏洩の解決
  • Androidメモリ最適化4-ピクチャ最適化
  • Androidパフォーマンス最適化5-メモリ最適化
  • Android性能最適化6-Hybridアプリケーション起動最適化