P: Como pode ocorrer vazamento de memória em Java?
R: Em Java, há muitos motivos para vazamentos de memória. Um exemplo típico é um código que não implementa hasCode e
A classe Key do método equals é salva no HashMap. No final, muitos objetos duplicados serão gerados. Todos os vazamentos de memória
No final, uma exceção OutOfMemoryError será lançada. Aqui está uma breve simulação de um vazamento de memória através de um loop infinito.
Explique com um exemplo.
Copie o código do código da seguinte forma:
importar java.util.HashMap;
importar java.util.Map;
classe pública MemoryLeak {
public static void main(String[] args) {
Mapa<Chave, String> mapa = new HashMap<Chave, String>(1000);
contador interno = 0;
enquanto (verdadeiro) {
// cria objetos duplicados devido a uma classe Key incorreta
map.put(new Key("dummyKey"), "valor");
contador++;
if (contador% 1000 == 0) {
System.out.println("tamanho do mapa: " + map.size());
System.out.println("Memória livre após contagem " + contador
+ "é" + getFreeMemory() + "MB");
dormir(1000);
}
}
}
// chave da classe interna sem hashcode() ou equals() – implementação incorreta
chave de classe estática {
chave de string privada;
chave pública(chave de string) {
esta.chave = chave;
}
}
//atraso por um determinado período em milissegundos
public static void sleep(long sleepFor) {
tentar {
Thread.sleep(sleepFor);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//obtém memória disponível em MB
public static long getFreeMemory() {
retornar Runtime.getRuntime().freeMemory() / (1024 * 1024);
}
}
O resultado é o seguinte:
Copie o código do código da seguinte forma:
tamanho do mapa: 1000
A memória livre após a contagem 1000 é de 4 MB
tamanho do mapa: 2000
A memória livre após a contagem 2.000 é de 4 MB
tamanho do mapa: 1396000
A memória livre após a contagem 1396000 é de 2 MB
tamanho do mapa: 1397000
A memória livre após a contagem 1397000 é de 2 MB
tamanho do mapa: 1398000
A memória livre após a contagem 1398000 é de 2 MB
tamanho do mapa: 1399000
A memória livre após a contagem 1399000 é de 1 MB
tamanho do mapa: 1400000
A memória livre após a contagem 1400000 é de 1 MB
tamanho do mapa: 1401000
A memória livre após a contagem 1401000 é de 1 MB
.....
.....
tamanho do mapa: 1452000
A memória livre após a contagem 1452000 é 0 MB
tamanho do mapa: 1453000
A memória livre após a contagem 1453000 é 0 MB
Exceção no thread "principal" java.lang.OutOfMemoryError: espaço de heap Java
em java.util.HashMap.addEntry(HashMap.java:753)
em java.util.HashMap.put(HashMap.java:385)
em MemoryLeak.main(MemoryLeak.java:10)
P: Como resolver o vazamento de memória acima?
R: Implemente os métodos equals e hasCode da classe Key.
Copie o código do código da seguinte forma:
.....
chave de classe estática {
chave de string privada;
chave pública(chave de string) {
esta.chave = chave;
}
@Substituir
público booleano igual a(Objeto obj) {
if (obj instância da chave)
retornar key.equals(((Key) obj).key);
outro
retornar falso;
}
@Substituir
public int hashCode() {
retornar chave.hashCode();
}
}
.....
A reexecução do programa produzirá os seguintes resultados:
Copie o código do código da seguinte forma:
tamanho do mapa: 1
A memória livre após a contagem 1000 é de 4 MB
tamanho do mapa: 1
A memória livre após a contagem 2.000 é de 4 MB
tamanho do mapa: 1
A memória livre após a contagem 3000 é de 4 MB
tamanho do mapa: 1
A memória livre após a contagem 4000 é de 4 MB
...
A memória livre após a contagem 73000 é de 4 MB
tamanho do mapa: 1
A memória livre após a contagem 74000 é de 4 MB
tamanho do mapa: 1
A memória livre após a contagem 75000 é de 4 MB
P: Em cenários reais, como você encontra vazamentos de memória?
R: Obtenha o ID do thread por meio do código a seguir
Copie o código do código da seguinte forma:
C:/>jps
5808Jps
4568 Vazamento de memória
3860 Principal
Abra o jconsole via linha de comando
Copie o código do código da seguinte forma:
C:/>jconsole 4568
A classe Key que implementa hasCode e equals e o gráfico que não a implementa são os seguintes:
Sem vazamento de memória:
Causa vazamento de memória: