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

来源:互联网 发布:access 多少条数据 编辑:程序博客网 时间:2024/05/21 06:24

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

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: 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)

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: 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

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

复制代码 代码如下:

C:\>jps
5808 Jps
4568 MemoryLeak
3860 Main

通过命令行打开jconsole

复制代码 代码如下:

C:\>jconsole 4568

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

没有内存泄露的:

造成内存泄露的:



您可能感兴趣的文章:

  • 详细介绍Java内存泄露原因
  • 理解Java中的内存泄露及解决方法示例
  • 浅谈Java编程中的内存泄露情况
 
Tags:Java内存泄露

相关文章

  • 2015-07-07java采用中文方式显示时间的方法
  • 2015-12-12详解Java的Hibernate框架中的注解与缓存
  • 2012-12-12java 全角半角字符转换如何实现
  • 2015-10-10Jsoup获取全国地区数据属性值(省市县镇村)
  • 2015-04-04java实现希尔排序算法
  • 2014-02-02java用静态工厂代替构造函数使用方法和优缺点
  • 2015-06-06sprng和struts有什么区别?
  • 2014-10-10教你构建第一个Java Applet程序
  • 2014-02-02Java策略模式的简单应用实现方法
  • 2015-11-11Java随手笔记8之包、环境变量和访问控制及maven profile实现多环

 

0 0
原创粉丝点击