zoukankan      html  css  js  c++  java
  • 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类和没有实现的图表如下所示:

    没有内存泄露的:

    造成内存泄露的:

  • 相关阅读:
    Python语言程序设计(1)--实例1和基本知识点
    前端学习笔记--函数
    知乎推荐书籍整理
    第六周周总结
    第五周总结
    第四周周总结
    第三周周总结
    第二周总结
    第一周总结
    项目目标
  • 原文地址:https://www.cnblogs.com/xhj123/p/java.html
Copyright © 2011-2022 走看看