This article comes from a hot discussion on the StackOverflow question and answer website: How to write a piece of code in Java that will cause a memory leak.
Q: I was in the interview just now, and the interviewer asked me how to write out the Java code that would be leaking memory. I have no idea of this problem, it's embarrassing.
A1: memory leaks can be easily generated by the following steps (program code cannot access some objects, but they are still in memory):
- The application creates a long-running thread (or, using a thread pool, a memory leak occurs faster).
- A thread loads a class from a class loader (which can be customized).
- The class allocates large chunks of memory (for example
new byte[1000000]
), stores a strong reference in a static variable, and then stores its own reference in Threadlocal. Allocating additional memory new byte[1000000]
is optional (class instance leaks are sufficient), but this can make memory leaks faster.
- The thread cleans up the custom class or loads the class loader for that class.
- Repeat the above steps.
Because there is no reference to the class and ClassLoader, the storage in threadlocal cannot be accessed. Threadlocal holds a reference to the object, which also holds a reference to the class and its classloader, which holds all references to the classes it loads, so that the GC cannot reclaim memory stored in threadlocal. In many JVM implementations, the Java class and ClassLoader are assigned directly to the PermGen zone without performing a GC, which results in a more serious memory leak.
One of the variants of this leak pattern is that if you frequently redeploy applications that use threadlocal in any form, application containers (such as Tomcat) are prone to memory leaks (because the application container uses the same thread as previously described, the new classloader will be used each time the app is redeployed).
A2:
Static variable Reference Object
class Memorableclass { staticfinalnew ArrayList;}
That calls a long string ofString.intern()
// read lengthy string any source db,textbox/jsp etc.. // This would place the string in memory pool from which you cant removestr.intern ();
Open stream is not closed (file, network, etc.)
Try { new BufferedReader (new FileReader (inputfile)); ... Catch (Exception e) { e.printstacktrace ();}
Connection not closed
Try { = connectionfactory.getconnection (); ... Catch (Exception e) { e.printstacktrace ();}
GC Unreachable zone for JVM
For example, the memory allocated through the native method.
Web application objects in the application scope, application not restarted or not explicitly removed
Getservletcontext (). SetAttribute ("Some_map", MAP);
Web Application object in session scope, not invalidated or not explicitly removed
Session.setattribute ("Some_map", MAP);
Incorrect or inappropriate JVM options
IBM JDK NOCLASSGC, for example, prevents garbage collection of useless classes
A3: If the hashset is not implemented correctly (or is not implemented) hashCode()
or equals()
, it causes a constant increase in the "copy" in the collection. If the collection cannot ignore the elements it should ignore, it will only grow in size and cannot delete the elements.
If you want to generate incorrect key-value pairs, you can do the following:
class Badkey { // no hashcode or Equals (); Public Final String key; Public this. Key == system.getproperties (); Map.put (new// Memory leak even if your threads die.
A4: except for forgotten listeners, static references, key errors/modifications in HashMap, or thread blocking cannot end a typical memory leak scenario such as a life cycle, here are some less obvious cases of memory leaks in Java, mainly thread-related.
Runtime.addShutdownHook
is not removed, even if Removeshutdownhook is used, the Threadgroup class may not be reclaimed due to a bug that does not start a thread, causing a memory leak in Threadgroup.
- The thread was created but not started, as is the case above
- Create inherited
ContextClassLoader
and AccessControlContext
used threads, ThreadGroup
and all InheritedThreadLocal
of these references are potential leaks, as well as all classes loaded by the ClassLoader and all static references, and so on. The impact of the ThreadFactory
interface as an important constituent element of the entire J.u.c.executor framework (java.util.concurrent) is obvious, and many developers are not aware of its potential dangers. And many libraries will start the thread as requested.
ThreadLocal
caching, in many cases, is not a good practice. There are many implementations of a simple cache based on threadlocal, but if a thread continues to run outside its expected life cycle contextclassloader will leak. Do not use the threadlocal cache unless it is really necessary.
- Called when Threadgroup itself has no threads but still has child thread groups
ThreadGroup.destroy()
. A memory leak occurs that causes the thread group to not be removed from its parent thread group and cannot enumerate the child thread groups.
- Using Weakhashmap,value to refer to key directly (indirectly) is a difficult situation to find. This also applies to inherited
Weak/SoftReference
classes that may hold strong references to protected objects.
- Download resources using the HTTP (s) protocol
java.net.URL
. KeepAliveCache
creating a new thread in system Threadgroup causes the current thread's context class loader memory to leak. A thread is created on the first request when there is no surviving thread, so a leak is most likely to occur. (It has been fixed in Java7 that the code to create the thread reasonably removes the context ClassLoader.) )
- Used
InflaterInputStream
in constructors (for example PNGImageDecoder
) to pass new java.util.zip.Inflater()
, not call Inflater end()
. Only new words are very safe, but if you create the class as a constructor parameter, the call flow close()
cannot be closed inflater, a memory leak can occur. This is not a real memory leak because it will be released by finalizer. But this consumes a lot of native memory, causing the Linux oom_killer to kill the process. So the lesson here is: release native resources as early as possible.
java.util.zip.Deflater
Also, the situation is even more serious. A good place may be seldom used Deflater
. If you create it yourself Deflater
or Inflater
remember that you must call it end()
.
How to write a piece of code in Java to trigger a memory leak