Android 仮想マシンのガベージ コレクションの原則
Android 仮想マシンは Java ベースの Dalvik 仮想マシンを使用し、そのガベージ コレクション メカニズムは Java 仮想マシンのメカニズムと似ています。Dalvik 仮想マシンでのガベージ コレクションは、世代別ガベージ コレクションと同時ガベージ コレクションの 2 つの方法に分けられます。
まず、Dalvik 仮想マシンは世代別ガベージ コレクション メカニズムを使用して、すべての Java オブジェクトを 3 つの世代 (Young Generation、Old Generation、および Permanent Generation) に分割します。オブジェクトが作成されると、Young Generation に割り当てられます。Young Generation のオブジェクトの場合、メモリが不足すると、マイナー GC (Young Generation ガベージ コレクション) がトリガーされます。マイナー GC は、若い世代のオブジェクトのみをスキャンし、到達不能なオブジェクトをすべて消去して、残りのオブジェクトを古い世代に移動します。
旧世代のオブジェクトの場合、メモリが不足すると、メジャー GC (旧世代のガベージ コレクション) がトリガーされます。メジャー GC は、ヒープ全体のすべてのオブジェクトをスキャンし、到達不能なオブジェクトをすべてクリーンアップして、残りのオブジェクトを古い世代に保持します。Permanent Generation は、静的オブジェクトと定数を格納するために使用される領域であり、ガベージ コレクションには参加しません。
世代別ガベージ コレクションに加えて、Dalvik 仮想マシンは、マーク スイープ アルゴリズムに基づく同時ガベージ コレクション メカニズムも使用します。このリサイクル メカニズムは、システムが正常に動作しているときにガベージ コレクション操作を実行できます。1 つ目は、すべての到達不能オブジェクトをマークすることによるマーキング フェーズです。到達不能なオブジェクトは、クリーンアップ フェーズで再利用されます。
Java メモリと非 Java メモリのガベージ コレクション
Android 仮想マシンのガベージ コレクション メカニズムは 2 つの部分で構成されています
Java メモリのガベージ コレクション
Javaメモリのガベージコレクションには、主に世代別ガベージコレクションと並行ガベージコレクションがあります。
世代別ガベージ コレクション: Java の世代別ガベージ コレクション メカニズムは、メモリをさまざまな領域に分割し、各領域はさまざまな年齢のオブジェクトを管理します。若い世代の領域では、ガベージ コレクションによってプログラムが停止することはありませんが、古い世代の領域では、ガベージ コレクションによってプログラムが停止する可能性があります。ガベージ コレクションは、領域のメモリ使用量が制限を超えるとトリガーされます。
コンカレント ガベージ コレクション: コンカレント ガベージ コレクションは、アプリケーションの正常な実行中にオペレーティング システムと同時に実行されるガベージ コレクション メカニズムです。コンカレント ガベージ コレクション中に、仮想マシンはスレッドを開始して未使用のオブジェクトをマークおよびクリーンアップし、メモリ領域を解放します。
Java 以外のメモリのガベージ コレクション
Java オブジェクトに加えて、Android アプリケーションは、Bitmap、JNI オブジェクト、およびリソースなど、Java 以外のメモリも大量に使用します。これらのオブジェクトは Java ガベージ コレクション メカニズムによって管理されないため、処理には特別なガベージ コレクション メカニズムが必要です。
Java 以外のメモリのガベージ コレクションでは、主に Bitmap のリサイクルが含まれます。ビットマップは多くのメモリを占有するオブジェクトであり、不適切な使用はメモリの問題を簡単に引き起こす可能性があります。Android には、Bitmap オブジェクトが占有するメモリ領域を解放するための bitmap.recycle() メソッドが用意されています。アプリケーションを終了する前にすべてのビットマップを手動でリサイクルすると、メモリ リークやアプリケーションのクラッシュなどの問題を回避できます。
一般に、Android 仮想マシンのガベージ コレクション メカニズムは、Java メモリと非 Java メモリのガベージ コレクション メカニズムを通じてメモリを効果的に管理し、システムのパフォーマンスと安定性を向上させることです。実際のアプリケーションでは、メモリ リークやアプリケーションのクラッシュなどの問題を回避するために、プログラマは実際のニーズに応じてメモリとガベージ コレクションのメカニズムを合理的に使用する必要があります。
Android仮想マシンに基づくガベージコレクションの実際のコード
java
public class MainActivity extends AppCompatActivity {
private String[] arr = new String[10000];
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
for (int i=0; i<10000; i++) {
arr[i] = Integer.toString(i);
}
}
@Override
protected void onResume() {
super.onResume();
updateUI();
}
private void updateUI() {
StringBuilder stringBuilder = new StringBuilder();
for (String s : arr) {
stringBuilder.append(s).append("\n");
}
textView.setText(stringBuilder.toString());
}
@Override
protected void onDestroy() {
super.onDestroy();
//手动调用垃圾回收机制
System.gc();
}
}
このコードは、サイズが 10000 の文字列配列を作成し、onResume メソッドで UI を更新し、最後に onDestroy メソッドでガベージ コレクション メカニズムを手動で呼び出すことができます。この例では、UI が更新されるたびに、新しい StringBuilder オブジェクトが作成され、配列内の文字列がループによって連結されます。ガベージ コレクション メカニズムを手動で呼び出さないと、これらの未使用の StringBuilder オブジェクトと文字列オブジェクトが常にメモリを占有するため、メモリ リークやアプリケーションのクラッシュが発生する可能性があります。ガベージ コレクション メカニズムを手動で呼び出すことにより、これらの到達不能オブジェクトをクリアし、メモリ空間を解放して、アプリケーションの安定性とパフォーマンスを保証できます。
要約する
Android 仮想マシンのガベージ コレクション メカニズムの動作プロセスは、主に次の段階に分けられます。
- メモリ割り当てフェーズ: アプリケーションが新しいクラスをロードするか、新しいオブジェクトを作成する必要がある場合、Android 仮想マシンは必要に応じてメモリ領域を動的に割り当てます。
- 世代別リサイクル フェーズ: Android 仮想マシンは、世代別ガベージ コレクション メカニズムを採用して、メモリを異なる世代に分割します. 異なる世代のオブジェクト ライフ サイクルに従って、メモリの使用を最適化するために、リサイクルのために異なるガベージ コレクション戦略が選択されます.
- 同時マーキング フェーズ: アプリケーションが正常に実行されている場合、Android 仮想マシンはスレッドを開始して、ヒープ メモリを同時にマークし、後続のクリーニング操作のために残りのオブジェクトをマークします。
- コンカレント クリーニング フェーズ:コンカレント マーキング フェーズが終了すると、仮想マシンはスレッドを開始して到達不能オブジェクトをクリーンアップし、メモリ領域を再利用します。
- 物理メモリ圧縮ステージ: メモリ使用量が高すぎる場合、Android 仮想マシンは物理メモリ圧縮ステージを開始して、メモリ スペースを解放し、メモリの断片化を減らします。