Q: How can memory leak occur in Java?
A: In Java, there are many reasons for memory leaks. A typical example is a Key class that does not implement the hasCode and
equals methods and is saved in a HashMap. In the end, many duplicate objects will be generated. All memory leaks
will eventually throw an OutOfMemoryError exception. The following is a brief example of simulating a memory leak through an infinite loop
.
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);
}
}The results are as follows:
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: How to solve the above memory leak?
A: Implement the equals and hasCode methods of the Key class.
.....
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();
}
}
.....Re-executing the program will get the following results:
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: In actual scenarios, how do you find memory leaks?
A: Get the thread ID through the following code
C:\>jps 5808 Jps 4568 MemoryLeak 3860 Main
Open jconsole through the command line
C:\>jconsole 4568
The Key class that implements hasCode and equals and the chart that does not implement it are as follows:
No memory leak:

Cause memory leak:

More typical memory in Java For articles related to leakage problems and solutions, please pay attention to the PHP Chinese website!