Java中典型的内存泄露问题和解决方法
程序员文章站
2024-02-26 15:13:22
q:在java中怎么可以产生内存泄露?a:java中,造成内存泄露的原因有很多种。典型的例子是一个没有实现hascode和equals方法的key类在hashmap中保存的...
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类和没有实现的图表如下所示:
没有内存泄露的:
造成内存泄露的: