java内存泄漏的经典案例

这篇文章主要介绍了Java中典型的内存泄露问题和解决方法,典型的内存泄露例子是一个没有实现hasCode和 equals方法的Key类在HashMap中保存的情况,可以通过实现Key类的equals和hasCode方法解决这种内存泄漏问题,需要的朋友可以参考下。

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

 1 import java.util.HashMap;
 2 import java.util.Map;
 3 
 4 public class MemoryLeak {
 5 
 6  public static void main(String[] args) {
 7   Map<Key, String> map = new HashMap<Key, String>(1000);
 8 
 9   int counter = 0;
10   while (true) {
11        // creates duplicate objects due to bad Key class
12    map.put(new Key("dummyKey"), "value");
13    counter++;
14    if (counter % 1000 == 0) {
15     System.out.println("map size: " + map.size());
16     System.out.println("Free memory after count " + counter
17       + " is " + getFreeMemory() + "MB");
18 
19     sleep(1000);
20    }
21 
22     
23   }
24  }
25 
26  // inner class key without hashcode() or equals() -- bad implementation
27  static class Key {
28   private String key;
29 
30   public Key(String key) {
31    this.key = key;
32   }
33 
34  }
35 
36  //delay for a given period in milli seconds
37  public static void sleep(long sleepFor) {
38   try {
39    Thread.sleep(sleepFor);
40   } catch (InterruptedException e) {
41    e.printStackTrace();
42   }
43  }
44 
45  //get available memory in MB
46  public static long getFreeMemory() {
47   return Runtime.getRuntime().freeMemory() / (1024 * 1024);
48  }
49 
50 }
51 结果如下:
52 复制代码 代码如下:
53 
54 map size: 1000
55 Free memory after count 1000 is 4MB
56 map size: 2000
57 Free memory after count 2000 is 4MB
58 map size: 1396000
59 Free memory after count 1396000 is 2MB
60 map size: 1397000
61 Free memory after count 1397000 is 2MB
62 map size: 1398000
63 Free memory after count 1398000 is 2MB
64 map size: 1399000
65 Free memory after count 1399000 is 1MB
66 map size: 1400000
67 Free memory after count 1400000 is 1MB
68 map size: 1401000
69 Free memory after count 1401000 is 1MB
70 .....
71 .....
72 map size: 1452000
73 Free memory after count 1452000 is 0MB
74 map size: 1453000
75 Free memory after count 1453000 is 0MB
76 Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
77  at java.util.HashMap.addEntry(HashMap.java:753)
78  at java.util.HashMap.put(HashMap.java:385)
79  at MemoryLeak.main(MemoryLeak.java:10)

Q:怎么解决上面的内存泄露?
A:实现Key类的equals和hasCode方法。

 1   .....
 2 static class Key {
 3  private String key;
 4 
 5  public Key(String key) {
 6   this.key = key;
 7  }
 8 
 9  
10  @Override
11  public boolean equals(Object obj) {
12 
13   if (obj instanceof Key)
14    return key.equals(((Key) obj).key);
15   else
16    return false;
17 
18  }
19 
20  @Override
21  public int hashCode() {
22   return key.hashCode();
23  }
24 }
25 .....

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

 1  map size: 1
 2 Free memory after count 1000 is 4MB
 3 map size: 1
 4 Free memory after count 2000 is 4MB
 5 map size: 1
 6 Free memory after count 3000 is 4MB
 7 map size: 1
 8 Free memory after count 4000 is 4MB
 9 ...
10 Free memory after count 73000 is 4MB
11 map size: 1
12 Free memory after count 74000 is 4MB
13 map size: 1
14 Free memory after count 75000 is 4MB

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

1 C:\>jps
2 5808 Jps
3 4568 MemoryLeak
4 3860 Main

通过命令行打开jconsole

1 C:\>jconsole 4568

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

没有内存泄露的:

造成内存泄露的:

 

转载于:https://www.cnblogs.com/xhj123/p/java.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值