Java中典型的内存泄露问题和解决方法

Q:在Java中怎么可以产生内存泄露?A:Java中,造成内存泄露的原因有很多种。典型的例子是一个没有实现hasCode和equals方法的Key类在HashMap中保存的情况。最后会生成很多重复的对象。所有的内存泄露最后都会抛出OutOfMemoryError异常,下面通过一段简短的通过无限循环模拟内存泄露的例子说明一下。

代码如下:
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); }}

结果如下:

代码如下:
map size: 1000Free memory after count 1000 is 4MBmap size: 2000Free memory after count 2000 is 4MBmap size: 1396000Free memory after count 1396000 is 2MBmap size: 1397000Free memory after count 1397000 is 2MBmap size: 1398000Free memory after count 1398000 is 2MBmap size: 1399000Free memory after count 1399000 is 1MBmap size: 1400000Free memory after count 1400000 is 1MBmap size: 1401000Free memory after count 1401000 is 1MB..........map size: 1452000Free memory after count 1452000 is 0MBmap size: 1453000Free memory after count 1453000 is 0MBException 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:怎么解决上面的内存泄露?A:实现Key类的equals和hasCode方法。 

代码如下:
    .....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(); }}..... 

 重新执行程序会得到如下结果: 

代码如下:
 map size: 1Free memory after count 1000 is 4MBmap size: 1Free memory after count 2000 is 4MBmap size: 1Free memory after count 3000 is 4MBmap size: 1Free memory after count 4000 is 4MB...Free memory after count 73000 is 4MBmap size: 1Free memory after count 74000 is 4MBmap size: 1Free memory after count 75000 is 4MB 

Q:在实际场景中,你怎么查找内存泄露?A:通过以下代码获取线程ID

代码如下:
C:\>jps5808 Jps4568 MemoryLeak3860 Main

通过命令行打开jconsole

代码如下:
C:\>jconsole 4568

实现了hasCode和equals的Key类和没有实现的图表如下所示:没有内存泄露的:

造成内存泄露的:

以上是 Java中典型的内存泄露问题和解决方法 的全部内容, 来源链接: utcz.com/p/206781.html

回到顶部