minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
A destruição da memória refere-se à criação e destruição de um grande número de objetos em um curto período de tempo, resultando em atividades frequentes de coleta de lixo (Garbage Collection, GC). Essa atividade frequente de GC consome muitos recursos da CPU e pode causar atrasos nos aplicativos ou degradação do desempenho.
Desempenho: A curva de memória está irregular.
Um vazamento de memória ocorre quando uma aplicação retém referências a objetos que não são mais necessários, fazendo com que esses objetos não sejam reciclados pelo coletor de lixo, ocupando assim espaço de memória que poderia ter sido liberado. Com o tempo, vazamentos de memória resultam em cada vez menos memória disponível, o que pode eventualmente levar a travamentos de aplicativos ou degradação de desempenho.
O estouro de memória ocorre quando um aplicativo tenta alocar mais espaço de memória, mas o sistema não consegue atender à solicitação porque não há mais espaço de memória suficiente para alocar. Isso geralmente faz com que o aplicativo gere uma exceção OutOfMemoryError.
Estrutura de memória Java: heap, pilha de máquina virtual, área de método, contador de programa, pilha de método local.
Algoritmo de reciclagem de memória Java:
Desvantagens do algoritmo mark-clear: A marcação e a limpeza não são eficientes e produzirão um grande número de fragmentos de memória descontínuos.
Algoritmo de replicação: simples de implementar e eficiente de executar. Desvantagens: Metade do espaço desperdiçado.
Algoritmo Mark-compact: evita a fragmentação da memória causada pela limpeza de marca e evita o desperdício de espaço do algoritmo de cópia.
A alocação elástica de memória do Android, o valor de alocação e o valor máximo são afetados por dispositivos específicos.
O algoritmo de reciclagem Dalvik e o algoritmo de reciclagem ART são mecanismos de coleta de lixo usados para gerenciamento de memória no sistema operacional Android.
Algoritmo de reciclagem Dalvik:
Algoritmo de reciclagem de arte:
Mecanismo 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);
}
}
O Memory Profiler pode visualizar alocações de memória, clique em "Registrar alocações Java/Kotlin".
Significado do acima:
Os seguintes significados:
malloc()
ounew
O número de objetos alocados pelo operador.free()
oudelete
O número de objetos desalocados pelo operador.Análise da imagem acima:
Os valores de Alocações e Desalocações nesta área são relativamente semelhantes, e o Tamanho Raso é relativamente grande, indicando que objetos podem ser criados e destruídos com frequência.
Após clicar, você pode visualizar as informações da pilha de chamadas e, combinadas com o código, pode inferir que há um problema de instabilidade de memória no manipulador.
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() {
}
}
Adicione bibliotecas dependentes:
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14'
Após ocorrer um vazamento de memória, o LeakCanary irá gerar informações relevantes e despejá-las automaticamente:
Como pode ser visto na figura acima: LeakActivity apresenta vazamento de memória e o relacionamento da cadeia de referência é exibido.
Claro, você também pode gerar um arquivo hprof e visualizar informações específicas por meio da ferramenta Profiler:
Como pode ser visto na imagem acima: ocorreram 10 pontos de vazamento, incluindo LeakActivity. Clique em LeakActivity para visualizar o objeto com vazamento de memória e verificar a cadeia de referência.
Se você não liberar os recursos da imagem após usar o Bitmap, é fácil causarVazamento de memória, resultando em estouro de memória。
Reciclagem de memória:
Bitmap.recycle()
Execute a reciclagem de bitmap.Configuração de pixels de bitmap:
Configuração | Tamanho do byte ocupado (byte) | ilustrar |
---|---|---|
ALFA_8 | 1 | único canal transparente |
RGB_565 | 2 | Matiz RGB simples |
ARGB_8888 | 4 | Cor verdadeira de 24 bits |
RGBA_F16 | 8 | Android 8.0 novo (HDR) |
Calcule a memória ocupada pelo Btimap:
Problema no arquivo de recursos:
Código de teste:
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
*/
ilustrar:
1dp em dispositivos mdpi1px, 1dp em dispositivos xhdpi2px, 1dp==3px no dispositivo xxhdpi.
Portanto, o dispositivo atual é xxhdpi, então a largura da mesma imagem no recurso xxhdpi é 858, no recurso mdpi ela será ampliada 3 vezes e a largura é 2574, e no recurso xhdpi será ampliada 1,5 vezes e a largura é 1287.