informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Memory thrashing mengacu pada pembuatan dan penghancuran sejumlah besar objek dalam waktu singkat, yang mengakibatkan seringnya dilakukan aktivitas pengumpulan sampah (Garbage Collection, GC). Aktivitas GC yang sering dilakukan ini menghabiskan banyak sumber daya CPU dan dapat menyebabkan kelambatan aplikasi atau penurunan kinerja.
Performa: Kurva memori tidak rata.
Kebocoran memori terjadi ketika aplikasi menyimpan referensi ke objek yang tidak diperlukan lagi, menyebabkan objek tersebut gagal diambil kembali oleh pengumpul sampah, sehingga menempati ruang memori yang sebenarnya bisa dikosongkan. Seiring waktu, kebocoran memori mengakibatkan semakin sedikitnya memori yang tersedia, yang pada akhirnya dapat menyebabkan aplikasi mogok atau penurunan kinerja.
Memory overflow terjadi ketika aplikasi mencoba mengalokasikan lebih banyak ruang memori, namun sistem tidak dapat memenuhi permintaan tersebut karena tidak ada lagi ruang memori yang cukup untuk dialokasikan. Hal ini biasanya menyebabkan aplikasi mengeluarkan pengecualian OutOfMemoryError.
Struktur memori Java: tumpukan, tumpukan mesin virtual, area metode, penghitung program, tumpukan metode lokal.
Algoritma daur ulang memori Java:
Kekurangan dari algoritma mark-clear: Penandaan dan pembersihan tidak efisien dan akan menghasilkan sejumlah besar fragmen memori yang terputus-putus.
Algoritma replikasi: mudah diterapkan dan efisien untuk dijalankan. Kekurangan: Membuang separuh ruang.
Algoritme mark-compact: menghindari fragmentasi memori yang disebabkan oleh mark-clean dan menghindari pemborosan ruang pada algoritma penyalinan.
Alokasi elastis memori Android, nilai alokasi, dan nilai maksimum dipengaruhi oleh perangkat tertentu.
Algoritma daur ulang Dalvik dan algoritma daur ulang ART keduanya merupakan mekanisme pengumpulan sampah yang digunakan untuk manajemen memori di sistem operasi Android.
Algoritma daur ulang Dalvik:
Algoritma daur ulang seni:
Mekanisme LMK:
public class ShakeActivity extends AppCompatActivity {
private static Handler mHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
String str = "";
for (int i = 0; i < 10000000; i++) {
str += i;
}
mHandler.sendEmptyMessageDelayed(1, 30);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shake);
}
public void startClick(View view) {
mHandler.sendEmptyMessage(1);
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
}
Memory Profiler dapat melihat alokasi memori, klik "Rekam alokasi Java/Kotlin".
Arti di atas:
Arti berikut:
malloc()
ataunew
Jumlah objek yang dialokasikan oleh operator.free()
ataudelete
Jumlah objek yang dibatalkan alokasinya oleh operator.Analisis gambar di atas:
Nilai Alokasi dan Deallokasi pada area ini relatif sama, dan Ukuran Dangkalnya relatif besar, menunjukkan bahwa objek mungkin sering dibuat dan dimusnahkan.
Setelah mengklik, Anda dapat melihat informasi tumpukan panggilan, dan dikombinasikan dengan kode, Anda dapat menyimpulkan bahwa ada masalah jitter memori di Handler.
public class CallbackManager {
public static ArrayList<Callback> sCallbacks = new ArrayList<>();
public static void addCallback(Callback callback) {
sCallbacks.add(callback);
}
public static void removeCallback(Callback callback) {
sCallbacks.remove(callback);
}
}
public class LeakActivity extends AppCompatActivity implements Callback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_leak);
ImageView imageView = findViewById(R.id.imageView);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.splash);
imageView.setImageBitmap(bitmap);
CallbackManager.addCallback(this);
}
@Override
public void onOperate() {
}
}
Tambahkan perpustakaan dependen:
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14'
Setelah terjadi kebocoran memori, LeakCanary akan menghasilkan informasi yang relevan dan secara otomatis membuangnya:
Seperti yang terlihat dari gambar di atas: LeakActivity mengalami kebocoran memori, dan hubungan rantai referensi ditampilkan.
Tentu saja, Anda juga dapat membuat file hprof dan melihat informasi spesifik melalui alat Profiler:
Seperti terlihat dari gambar di atas: 10 titik kebocoran telah terjadi, termasuk LeakActivity. Klik pada LeakActivity untuk melihat objek memori yang bocor dan memeriksa rantai referensi.
Jika Anda tidak melepaskan sumber daya gambar setelah menggunakan Bitmap, hal ini mudah terjadiKebocoran memori, mengakibatkan memori meluap。
Daur ulang memori:
Bitmap.recycle()
Lakukan daur ulang Bitmap.Konfigurasi piksel bitmap:
Konfigurasi | Ukuran byte yang ditempati (byte) | menjelaskan |
---|---|---|
ALFA_8 | 1 | saluran transparan tunggal |
RGB_565 | 2 | Warna RGB sederhana |
ARGB_8888 | 4 | Warna asli 24-bit |
RGBA_F16 | 8 | Android 8.0 Baru (HDR) |
Hitung memori yang ditempati oleh Btimap:
Masalah file sumber daya:
Kode tes:
private void printBitmap(Bitmap bitmap, String drawable) {
String builder = drawable +
" Bitmap占用内存:" +
bitmap.getByteCount() +
" width:" +
bitmap.getWidth() +
" height:" +
bitmap.getHeight() +
" 1像素占用大小:" +
getByteBy1px(bitmap.getConfig());
Log.e("TAG", builder);
}
private int getByteBy1px(Bitmap.Config config) {
if (Bitmap.Config.ALPHA_8.equals(config)) {
return 1;
} else if (Bitmap.Config.RGB_565.equals(config)) {
return 2;
} else if (Bitmap.Config.ARGB_8888.equals(config)) {
return 4;
}
return 1;
}
// 逻辑密度
float density = metrics.density;
// 物理密度
int densityDpi = metrics.densityDpi;
Log.e("TAG", density + "-" + densityDpi);
// 1倍图
Bitmap bitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.splash1);
printBitmap(bitmap1, "drawable-mdpi");
// 2倍图
Bitmap bitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.splash2);
printBitmap(bitmap2, "drawable-xhdpi");
// 3倍图
Bitmap bitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.splash3);
printBitmap(bitmap3, "drawable-xxhdpi");
// 4倍图
Bitmap bitmap4 = BitmapFactory.decodeResource(getResources(), R.drawable.splash4);
printBitmap(bitmap4, "drawable-xxxhdpi");
// drawable
Bitmap bitmap5 = BitmapFactory.decodeResource(getResources(), R.drawable.splash);
printBitmap(bitmap5, "drawable");
/*
3.0-480
drawable-mdpi Bitmap占用内存:37127376 width:2574 height:3606 1像素占用大小:4
drawable-xhdpi Bitmap占用内存:9281844 width:1287 height:1803 1像素占用大小:4
drawable-xxhdpi Bitmap占用内存:4125264 width:858 height:1202 1像素占用大小:4
drawable-xxxhdpi Bitmap占用内存:2323552 width:644 height:902 1像素占用大小:4
drawable Bitmap占用内存:37127376 width:2574 height:3606 1像素占用大小:4
*/
menjelaskan:
1dp pada perangkat mdpi1px, 1dp pada perangkat xhdpi2px, 1dp==3px pada perangkat xxhdpi.
Oleh karena itu, perangkat saat ini adalah xxhdpi, jadi lebar gambar yang sama di bawah sumber daya xxhdpi adalah 858, di bawah sumber daya mdpi akan diperbesar 3 kali dan lebarnya 2574, dan di bawah sumber daya xhdpi akan diperbesar 1,5 kali dan lebarnya 1287.