Maison  >  Article  >  Java  >  Problèmes typiques de fuite de mémoire et solutions en Java

Problèmes typiques de fuite de mémoire et solutions en Java

高洛峰
高洛峰original
2017-01-16 16:07:311551parcourir

Q : Comment une fuite de mémoire peut-elle se produire en Java ?
R : En Java, les fuites de mémoire peuvent avoir de nombreuses causes. Un exemple typique est une classe Key qui n'implémente pas les méthodes hasCode et
equals et est enregistrée dans un HashMap. Au final, de nombreux objets en double seront générés. Toutes les fuites de mémoire
finiront par lever une exception OutOfMemoryError. Ce qui suit est un bref exemple de simulation d'une fuite de mémoire
via une boucle infinie.

import java.util.HashMap;
import java.util.Map;

public class MemoryLeak {

 public static void main(String[] args) {
  Map<Key, String> map = new HashMap<Key, String>(1000);

  int counter = 0;
  while (true) {
       // creates duplicate objects due to bad Key class
   map.put(new Key("dummyKey"), "value");
   counter++;
   if (counter % 1000 == 0) {
    System.out.println("map size: " + map.size());
    System.out.println("Free memory after count " + counter
      + " is " + getFreeMemory() + "MB");

    sleep(1000);
   }

    
  }
 }

 // inner class key without hashcode() or equals() -- bad implementation
 static class Key {
  private String key;

  public Key(String key) {
   this.key = key;
  }

 }

 //delay for a given period in milli seconds
 public static void sleep(long sleepFor) {
  try {
   Thread.sleep(sleepFor);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }

 //get available memory in MB
 public static long getFreeMemory() {
  return Runtime.getRuntime().freeMemory() / (1024 * 1024);
 }

}

Les résultats sont les suivants :

map size: 1000
Free memory after count 1000 is 4MB
map size: 2000
Free memory after count 2000 is 4MB
map size: 1396000
Free memory after count 1396000 is 2MB
map size: 1397000
Free memory after count 1397000 is 2MB
map size: 1398000
Free memory after count 1398000 is 2MB
map size: 1399000
Free memory after count 1399000 is 1MB
map size: 1400000
Free memory after count 1400000 is 1MB
map size: 1401000
Free memory after count 1401000 is 1MB
.....
.....
map size: 1452000
Free memory after count 1452000 is 0MB
map size: 1453000
Free memory after count 1453000 is 0MB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
 at java.util.HashMap.addEntry(HashMap.java:753)
 at java.util.HashMap.put(HashMap.java:385)
 at MemoryLeak.main(MemoryLeak.java:10)

Q : Comment résoudre la fuite de mémoire ci-dessus ?
A : Implémentez les méthodes equals et hasCode de la classe Key.

    .....
static class Key {
 private String key;

 public Key(String key) {
  this.key = key;
 }

 
 @Override
 public boolean equals(Object obj) {

  if (obj instanceof Key)
   return key.equals(((Key) obj).key);
  else
   return false;

 }

 @Override
 public int hashCode() {
  return key.hashCode();
 }
}
.....

La réexécution du programme obtiendra les résultats suivants :

 map size: 1
Free memory after count 1000 is 4MB
map size: 1
Free memory after count 2000 is 4MB
map size: 1
Free memory after count 3000 is 4MB
map size: 1
Free memory after count 4000 is 4MB
...
Free memory after count 73000 is 4MB
map size: 1
Free memory after count 74000 is 4MB
map size: 1
Free memory after count 75000 is 4MB

Q : Dans des scénarios réels, comment trouvez-vous les fuites de mémoire ?
A : Obtenez l'ID du fil via le code suivant

C:\>jps
5808 Jps
4568 MemoryLeak
3860 Main

Ouvrez jconsole via la ligne de commande

C:\>jconsole 4568

La classe Key qui implémente hasCode et égal et le graphique sans implémentation sont les suivants :

Aucune fuite de mémoire :

Problèmes typiques de fuite de mémoire et solutions en Java

Provoquant une fuite de mémoire :

Problèmes typiques de fuite de mémoire et solutions en Java

Plus de Java Pour les articles liés aux problèmes typiques de fuite de mémoire et aux solutions, veuillez prêter attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn