源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2021-12-04 18:35 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Java中典型的内存泄露问题和解决方法
[b]Q:在Java中怎么可以产生内存泄露? [/b]A:Java中,造成内存泄露的原因有很多种。典型的例子是一个没有实现hasCode和 equals方法的Key类在HashMap中保存的情况。最后会生成很多重复的对象。所有的内存泄露 最后都会抛出OutOfMemoryError异常,下面通过一段简短的通过无限循环模拟内存泄露 的例子说明一下。
[u]复制代码[/u] 代码如下:
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);  } }
结果如下:
[u]复制代码[/u] 代码如下:
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)
[b]Q:怎么解决上面的内存泄露? [/b]A:实现Key类的equals和hasCode方法。  
[u]复制代码[/u] 代码如下:
    ..... 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();  } } .....  
 重新执行程序会得到如下结果:  
[u]复制代码[/u] 代码如下:
 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  
[b]Q:在实际场景中,你怎么查找内存泄露? [/b]A:通过以下代码获取线程ID
[u]复制代码[/u] 代码如下:
C:>jps 5808 Jps 4568 MemoryLeak 3860 Main
通过命令行打开jconsole
[u]复制代码[/u] 代码如下:
C:>jconsole 4568
实现了hasCode和equals的Key类和没有实现的图表如下所示: 没有内存泄露的: [img]http://img.1sucai.cn/uploads/article/2018010710/20180107100134_0_69673.jpg?201432883453[/img] 造成内存泄露的: [img]http://img.1sucai.cn/uploads/article/2018010710/20180107100134_1_60061.jpg?201432883656[/img]
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部