Heim  >  Artikel  >  Java  >  Typische Speicherleckprobleme und Lösungen in Java

Typische Speicherleckprobleme und Lösungen in Java

高洛峰
高洛峰Original
2017-01-16 16:07:311547Durchsuche

F: Wie kann es in Java zu einem Speicherverlust kommen?
A: In Java gibt es viele Gründe für Speicherlecks. Ein typisches Beispiel ist eine Key-Klasse, die die Methoden hasCode und
equals nicht implementiert und in einer HashMap gespeichert ist. Am Ende werden viele doppelte Objekte generiert. Alle Speicherlecks
lösen schließlich eine OutOfMemoryError-Ausnahme aus. Im Folgenden finden Sie ein kurzes Beispiel für die Simulation eines Speicherlecks
durch eine Endlosschleife.

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);
 }

}

Die Ergebnisse sind wie folgt:

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)

F: Wie kann der oben genannte Speicherverlust behoben werden?
A: Implementieren Sie die Methoden equal und hasCode der Key-Klasse.

    .....
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();
 }
}
.....

Eine erneute Ausführung des Programms führt zu folgenden Ergebnissen:

 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

F: Wie finden Sie in tatsächlichen Szenarien Speicherlecks?
A: Holen Sie sich die Thread-ID über den folgenden Code

C:\>jps
5808 Jps
4568 MemoryLeak
3860 Main

Öffnen Sie jconsole über die Befehlszeile

C:\>jconsole 4568

Die Schlüsselklasse, die hasCode und equal implementiert, und das Diagramm ohne Implementierung sind wie folgt:

Kein Speicherverlust:

Typische Speicherleckprobleme und Lösungen in Java

Verursacht Speicherverlust:

Typische Speicherleckprobleme und Lösungen in Java

Mehr Java Für Artikel zu typischen Problemen und Lösungen bei Speicherverlusten achten Sie bitte auf die chinesische PHP-Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn