Java中典型的内存泄露问题和解决方法
2014-04-28 08:37
881 查看
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中典型的内存泄露问题和解决方法
- C# Webbrowser使用加载页面多少了内存泄露问题解决方法汇总
- ATS插件开发中内存泄露问题的解决方法探讨
- 内存泄露java.lang.OutOfMemoryError: PermGen space解决方法
- 理解Java中的内存泄露及解决方法示例
- java反射造成的内存泄露解决方法
- PHP CURL 内存泄露问题解决方法
- 编译android遇到java虚拟机堆内存不够的问题 java.lang.OutOfMemoryError: GC overhead limit exceeded 解决方法
- Flex中Module的使用以及内存泄露问题解决方法
- UIWebView的内存泄露问题解决方法
- 【转】ListView多种类型优化,Java内存泄露的理解和解决,Handle造成内存泄露解决方法合集
- PHP CURL 内存泄露问题解决方法
- C# Webbrowser使用加载页面多少了内存泄露问题解决方法汇总
- 内存泄露java.lang.OutOfMemoryError: PermGen space解决方法
- CBRUSH释放、CreateSolidBrush的内存释放与内存泄露问题及其解决方法
- c++ 导致内存泄露的一些小问题与解决方法
- javascript内存泄露问题的解决方法和辅助工具
- GDI对象错误:CBRUSH释放、CreateSolidBrush的内存释放与内存泄露问题及其解决方法
- C++ vector变量等导致内存泄露问题的解决方法