Java中典型的内存泄露问题和解决方法
Java中典型的内存泄露问题和解决方法
发布时间:2017-01-07 来源:查字典编辑
摘要:Q:在Java中怎么可以产生内存泄露?A:Java中,造成内存泄露的原因有很多种。典型的例子是一个没有实现hasCode和equals方法的...

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中典型的内存泄露问题和解决方法1

造成内存泄露的:

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

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Java学习
热门Java学习
编程开发子分类