Android原理暴露シリーズのVacantCellキャッシュ


Android携帯電話を操作したことがある人は、待機インタフェースでアイコンをドラッグするインタラクティブな効果に深い印象を持っているはずです.例えば、アイコンをドラッグすると、アイコンが浮かび上がってドラッグに伴って位置が変わり、ドラッグが解放されると、アイコンは自動的に近くの適切な空白のグリッドの位置を探します.Androidはこの効果を実現する過程で多くのプログラミング技術を採用しており,本稿で重点的に論じたVacantCellキャッシュが代表的である.
VacantCellキャッシュは主に同じタイプのオブジェクトに対するキャッシュメカニズムであり、このメカニズムの目的は、割り当てられたが期限切れのオブジェクトを多重化し、頻繁なnewの新しいオブジェクトを回避することである.オブジェクト割り当てはシステムリソースを消費することを知っています.頻繁に大量の割り当てが必要な場合、Androidプラットフォームではスタックメモリが不足し、システムが遅くなり、アプリケーションのエラーが発生して再起動するなどの深刻な問題が発生する可能性があります.ユーザが待機インタフェースでアイコンをドラッグすることは頻繁であるが,Androidの画面には空白のグリッドのアドレスアルゴリズムがこのVacantCellキャッシュを採用しており,頻繁なnewの大量の新しいオブジェクトを回避している.
VacantCellクラスの実装は簡単です.実装コードは50行未満です.
static final class VacantCell {

            int cellX;

            int cellY;

            int spanX;

            int spanY;

            // We can create up to 523 vacant cells on a 4x4 grid, 100 seems

            // like a reasonable compromise given the size of a VacantCell and

            // the fact that the user is not likely to touch an empty 4x4 grid

            // very often 

            private static final int POOL_LIMIT = 100;

            private static final Object sLock = new Object();

            private static int sAcquiredCount = 0;

            private static VacantCell sRoot;

            private VacantCell next;

            static VacantCell acquire() {

                synchronized (sLock) {

                    if (sRoot == null) {

                        return new VacantCell();

                    }


                    VacantCell info = sRoot;

                    sRoot = info.next;

                    sAcquiredCount--;

                    return info;

                }

            }

            void release() {

                synchronized (sLock) {

                    if (sAcquiredCount < POOL_LIMIT) {

                        sAcquiredCount++;

                        next = sRoot;

                        sRoot = this;

                    }

                }

            }

            @Override

            public String toString() {

                return "VacantCell[x=" + cellX + ", y=" + cellY + ", spanX=" + spanX +

                        ", spanY=" + spanY + "]";

            }

        }

VacantCellは実際にJava静的内部クラスであり、その外部クラスCellLayout.JAvaのコードパスはpackagesappsLauncher 2srccomandroidlauncher 2CellLayout.JAva(具体的にAndroid gingerbread Launcher単一モジュールのダウンロード方法は、ブログAndroidソースコードのダウンロードを参照してください.git cloneで単一ディレクトリのダウンロードを実現します).
次にVacantCellのバッファリング機構がどのように実現されるかを具体的に分析する.
cellX、cellY、spanX、spanYのいくつかのメンバーは、空白のグリッドの縦横インデックス番号と対応するセルのグリッド数を占めています.ここでは気にしなくてもいいです.
POOL_LIMITはキャッシュ可能なVacantCellの最大値を定義しており、注釈のように最大523個のVacantCellオブジェクトを割り当てることができますが、4 X 4のスクリーングリッド定義では100個のバッファ数で十分であるはずです.つまり、この100の数値は経験値であり、実際の状況に応じて柔軟に修正することができます.
sLockはJava Objectオブジェクトで、主に同期制御として使用されています.私たちは気にしなくてもいいです.
sAcquiredCountは非常に重要な変数であり、実際にはカウンタであり、現在何個のVacantCellオブジェクト値がキャッシュされているかをリアルタイムで統計します.このカウンタとPOOL_によるとLIMITはキャッシュオブジェクトがPOOL_を超えないように制御できます.LIMITの上限.
sRootおよびnextは、VacantCellオブジェクトチェーンストレージをキャッシュする2つのキーリファレンスであり、VacantCellオブジェクトチェーンテーブルのヘッダーと特定のVacantCellオブジェクトリンクの次のオブジェクトのリファレンスをそれぞれ表します.
では、VacantCellキャッシュの2つの重要な静的メソッドacquire()と非静的メソッドrelease()について説明します.
VacantCellの新しいオブジェクトが必要な場合、Launcherは静的内部クラスのVacantCellの静的メソッドacquire()を呼び出し、新しいVacantCellオブジェクトを取得します.ここで新しいオブジェクトを取得するのは、VacantCellオブジェクトではなくacquireオブジェクトであることに注意してください.acquireメソッドの内部を見ると、sRootがnullの場合、直接new VacantCellであり、直接returnである.この場合、実際にキャッシュが使用できないためである.sRootがnullでない場合、これはキャッシュされたVacantCellオブジェクトがあることを意味し、sRootが指すオブジェクトをチェーンテーブルから直接取り出し、sRootがあるオブジェクトが指すnextを新しいヘッダsRootとし、同時にsAcquiredCountカウントを1減少させる.これは実際には、チェーンテーブルからヘッダーを削除する典型的な操作であり、データ構造に詳しい友人はこれに慣れていると信じています.
acquire()メソッドがVacantCellチェーンキャッシュをどのように利用するかを提供する場合、release()メソッドはVacantCellチェーンキャッシュをどのように構築するかという問題を解決します.sAcquiredCountでは、このVacantCellオブジェクトキャッシュをどのように使用しますか?第一に、新しいVacantCellオブジェクトが必要な場合、直接new VacantCellオブジェクトではなく、VacantCellの静的メソッドacquire()を呼び出すことによってオブジェクトを取得する.第2に、VacantCellオブジェクトが期限切れで不要になった場合、そのオブジェクトを呼び出すrelease()メソッドは、この不要なオブジェクトをキャッシュに追加します.
なお、直接new VacantCellオブジェクトでも直接的な問題はないが、VacantCellキャッシュメカニズムが採用されていないことを意味する.オブジェクトが不要な場合にrelease()メソッドを呼び出すことを表示しなくても直接的な問題はありません.これは、VacantCellキャッシュチェーンテーブルにこのオブジェクトが追加されないことを意味します.チェーンテーブルの各ノードオブジェクトの参照関連がない場合、このオブジェクトは最終的にAndroidのDalvik仮想マシンによってゴミとして自動的に回収されます.
この論文では、Android LauncherモジュールVacantCellキャッシュの実装原理を詳細に分析し、同じタイプのJavaオブジェクトを頻繁に構築し、大量に解放する必要がある場合、類似のキャッシュメカニズムを採用することを考慮し、頻繁に対象を割り当てることによるメモリ不足の問題を効果的に解決する場合がある.
/*****************************************************************************************************************************************/
本文はオリジナルの文章で、転載は必ず出典を明記してください:http://blog.csdn.net/droidpioneer/article/details/6787571 
Android開発用機友情リンク:http://vpclub.octech.com.cn/ztewd/9495.html
 /******************************************************************************************************************************************/