当前位置: 移动技术网 > IT编程>开发语言>Java > Java中典型的内存泄露问题和解决方法

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

2019年07月22日  | 移动技术网IT编程  | 我要评论

论坛交流,古典家具论坛,回唐传

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类和没有实现的图表如下所示:

没有内存泄露的:

造成内存泄露的:



如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网