Creating a memory leak with Java
I just had an interview, and I was asked to create a memory leak with Java. Needless to say I felt pretty dumb having no clue on how to even start creating one.
What would an example be?
Here's a good way to create a true memory leak (objects inaccessible by running code but still stored in memory) in pure Java:
new byte[1000000]
), stores a strong reference to it in a static field, and then stores a reference to itself in a ThreadLocal. Allocating the extra memory is optional (leaking the Class instance is enough), but it will make the leak work that much faster. This works because the ThreadLocal keeps a reference to the object, which keeps a reference to its Class, which in turn keeps a reference to its ClassLoader. The ClassLoader, in turn, keeps a reference to all the Classes it has loaded.
(It was worse in many JVM implementations, especially prior to Java 7, because Classes and ClassLoaders were allocated straight into permgen and were never GC'd at all. However, regardless of how the JVM handles class unloading, a ThreadLocal will still prevent a Class object from being reclaimed.)
A variation on this pattern is why application containers (like Tomcat) can leak memory like a sieve if you frequently redeploy applications that happen to use ThreadLocals in any way. (Since the application container uses Threads as described, and each time you redeploy the application a new ClassLoader is used.)
Update : Since lots of people keep asking for it, here's some example code that shows this behavior in action.
Static field holding object reference [esp final field]
class MemorableClass {
static final ArrayList list = new ArrayList(100);
}
Calling String.intern()
on lengthy String
String str=readString(); // read lengthy string any source db,textbox/jsp etc..
// This will place the string in memory pool from which you can't remove
str.intern();
(Unclosed) open streams ( file , network etc... )
try {
BufferedReader br = new BufferedReader(new FileReader(inputFile));
...
...
} catch (Exception e) {
e.printStacktrace();
}
Unclosed connections
try {
Connection conn = ConnectionFactory.getConnection();
...
...
} catch (Exception e) {
e.printStacktrace();
}
Areas that are unreachable from JVM's garbage collector , such as memory allocated through native methods
In web applications, some objects are stored in application scope until the application is explicitly stopped or removed.
getServletContext().setAttribute("SOME_MAP", map);
Incorrect or inappropriate JVM options , such as the noclassgc
option on IBM JDK that prevents unused class garbage collection
See IBM jdk settings.
A simple thing to do is to use a HashSet with an incorrect (or non-existent) hashCode()
or equals()
, and then keep adding "duplicates". Instead of ignoring duplicates as it should, the set will only ever grow and you won't be able to remove them.
If you want these bad keys/elements to hang around you can use a static field like
class BadKey {
// no hashCode or equals();
public final String key;
public BadKey(String key) { this.key = key; }
}
Map map = System.getProperties();
map.put(new BadKey("key"), "value"); // Memory leak even if your threads die.
链接地址: http://www.djcxy.com/p/444.html
上一篇: 何时通过ArrayList使用LinkedList?
下一篇: 用Java创建内存泄漏