Foreword
This topic is already commonplace, the reason I carry her out again, because next to a children's shoes blogger recently wrote an article called "ThreadLocal memory leaks," the article, I am not a link, because the writing is really yes. . (A million words omitted)
focused on the finish, I was also asked senseless. Out of humanitarian concern, bloggers write a very shameless.
text
definition
First, we must first talk about the definition, because a bunch of people do not understand the difference between memory overflow and memory leaks.
Memory overflow (OutOfMemory): You have only ten dollars, but I find you to be a one hundred. I'm sorry, ah, I do not have so much money. (给不起)
Memory leaks (MemoryLeak): You have ten dollars, I'm looking for you for one. But the shameless bloggers, do not give it all to you. (没退还)
Relationship: multiple memory leaks can cause memory overflow. (Bloggers shameless to find you more money a few times, you have no money, is the truth.)
harm
ok, I have not encountered cases java program more and more cards in the project.
Because memory leaks will result in frequent Full GC
, and Full GC
will cause the program to stop, and finally the Crash. So, you will feel your program more cards, more cards, then you will be despised product manager. Incidentally, the reason why we JVM tuning, is to reduce Full GC
the appearance.
I remember I had once met when the project has just been good on the line. As the result of the accumulation of time, it reported OutOfMemoryError: PermGen space
.
When it comes to this PermGen space
, a sudden burst of power prehistoric, spewing out from the main body Bo, be sure to tell us about the method area, but go beyond that, after all, this is not talking about "jvm from entry to give up."
The method area : from java virtual machine specification, for each of the threads share of run-time memory area . It stores the configuration information of each class , e.g. runtime constant pool ( Runtime Constant Pool
), bytecode data content fields and methods, and constructors ordinary methods.
Mentioned above is the norm, implemented in different virtual machines inside is not the same, the most typical is the permanent generation of (PermGen space) and the element space (Metaspace) .
jdk1.8 before: implementation area called permanent generations. Because in a very long time ago, java class that is almost static , and rarely is unloaded and recovered, so they give a permanent generations Blair said. So , if you are in the project, found the heap and permanent generations have been growing, not declining, the rate of recovery simply can not keep up the pace, needless to say, this is almost certain be a memory leak.
After jdk1.8: Implementation of the area called the yuan space. Permanent generation of Java that tune is very difficult. Metadata generation may be permanently with each Full GC
occurrence moves. And substituting the permanent set is difficult to determine the size of the space. Thus , java class decides to allocate the metadata in local memory, the maximum voxel space allocated space available to the system memory. In this way, we avoid the generation of a permanent set the size of the problem. However , in this case, once the memory leak occurs, you will take a lot of local memory. If you find that your project in the local memory usage is abnormally high. Ah, that's a memory leak.
How to troubleshoot
(1) by jps
id find java process.
(2) top -p [pid]
find the maximum memory usage reaches
(3) jstat -gccause pid 20000
20 seconds every output Full GC
result
(4) found that Full GC
too many times, is essentially a memory leak. Generate dump
documents, tool analyzes which object too much aid. The basic problem to be able to locate where.
Examples
On StackOverflow, there is a problem, as shown in FIG.
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.
That is, roughly, because the interview is requested in writing programs for a memory leak, then the question of who suddenly ignorant force, so many chiefs have given the answer.
A case
of this example from the "algorithm" (fourth edition) a book, I simplified a bit
class stack{
Object data[1000];
int top = 0; public void push(Object o){ data[top++] = o; } public Object pop(Object o){ return data[--top]; } }
When data pops up from the inside of the stack, data pointing to the array element has also been retained pointer. So even if you pop the stack is empty, these elements make up the memory will not be recovered.
The solution is
public Object pop(Object o){
Object result = data[--top];
data[top] = null;
return result; }
Case II
In fact, this is a bunch of examples, these examples reasons cause memory leaks are similar, that is, without closing the stream , specifically, it can be a file stream, socket stream, the stream database connections, etc.
, as follows, did not close the file stream
try {
BufferedReader br = new BufferedReader(new FileReader(inputFile));
...
...
} catch (Exception e) { e.printStacktrace(); }
As another example, did not close the connection
try {
Connection conn = ConnectionFactory.getConnection();
...
...
} catch (Exception e) {
e.printStacktrace();
}
The solution is. . . Ah, we should be able. . You say you will not transfer close()
methods.
Case III
before talking about this case, everyone ThreadLocal
in Tomcat
there is to know what caused memory leaks. However, I have to say about this leak, and ThreadLocal itself has little relationship, I looked at the official website of the example given, basically belong to improper use.
In Tomcat's official website, record the problem. The address is: https://wiki.apache.org/tomcat/MemoryLeakProtection
However, the official website of this example, it may be difficult to understand, we slight modifications.
public class HelloServlet extends HttpServlet{ private static final long serialVersionUID = 1L; static class LocalVariable { private Long[] a = new Long[1024 * 1024 * 100]; } final static ThreadLocal<LocalVariable> localVariable = new ThreadLocal<LocalVariable>(); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { localVariable.set(new LocalVariable()); } }
Then look at the conf arranged at sever.xml
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
The maximum thread pool threads 150, a minimum of four threads
in Tomcat Connector component responsible for receiving and processing the request, a request to each, it will take a thread to the thread pool.
In this visit servlet
, the ThreadLocal
variable which is added the new LocalVariable()
instance, but not remove
so the variables with the thread back to the thread pool. In addition to the many visits to servlet
the same thread may not work with the thread pool inside, which will lead to more work inside thread pool threads will be a memory leak.
In addition, servlet
the doGet
method of creating inside the new LocalVariable()
time of using webappclassloader
.
Then the
LocalVariable
object is not released -> LocalVariable.class
no release -> webappclassloader
no release -> webappclassloader
load all the classes have not been released, also caused a memory leak.
In addition, you eclipse
are doing a reload operation, working inside the thread pool thread is always present, and the thread inside the threadLocal
variable has not been cleaned up. And reload time, will build a new webappclassloader
, repeat the above steps. Multi-reload several times, on memory overflow.
But after Tomcat7.0, you do every time reload
, it will clean up the thread pool thread work threadLocals
variables. Therefore, this problem after tomcat7.0, does not exist.
ps:ThreadLocal
the use Tomcat
under service environment to note that not every web request Operating procedures ThreadLocal
are unique. ThreadLocal
What is not equal to the life cycle of a Request
life cycle. ThreadLocal
Tightly bound with thread object, since Tomcat
the use of thread pool threads are possible reuse situation.
Foreword
This topic is already commonplace, the reason I carry her out again, because next to a children's shoes blogger recently wrote an article called "ThreadLocal memory leaks," the article, I am not a link, because the writing is really yes. . (A million words omitted)
focused on the finish, I was also asked senseless. Out of humanitarian concern, bloggers write a very shameless.
text
definition
First, we must first talk about the definition, because a bunch of people do not understand the difference between memory overflow and memory leaks.
Memory overflow (OutOfMemory): You have only ten dollars, but I find you to be a one hundred. I'm sorry, ah, I do not have so much money. (给不起)
Memory leaks (MemoryLeak): You have ten dollars, I'm looking for you for one. But the shameless bloggers, do not give it all to you. (没退还)
Relationship: multiple memory leaks can cause memory overflow. (Bloggers shameless to find you more money a few times, you have no money, is the truth.)
harm
ok, I have not encountered cases java program more and more cards in the project.
Because memory leaks will result in frequent Full GC
, and Full GC
will cause the program to stop, and finally the Crash. So, you will feel your program more cards, more cards, then you will be despised product manager. Incidentally, the reason why we JVM tuning, is to reduce Full GC
the appearance.
I remember I had once met when the project has just been good on the line. As the result of the accumulation of time, it reported OutOfMemoryError: PermGen space
.
When it comes to this PermGen space
, a sudden burst of power prehistoric, spewing out from the main body Bo, be sure to tell us about the method area, but go beyond that, after all, this is not talking about "jvm from entry to give up."
The method area : from java virtual machine specification, for each of the threads share of run-time memory area . It stores the configuration information of each class , e.g. runtime constant pool ( Runtime Constant Pool
), bytecode data content fields and methods, and constructors ordinary methods.
Mentioned above is the norm, implemented in different virtual machines inside is not the same, the most typical is the permanent generation of (PermGen space) and the element space (Metaspace) .
jdk1.8 before: implementation area called permanent generations. Because in a very long time ago, java class that is almost static , and rarely is unloaded and recovered, so they give a permanent generations Blair said. So , if you are in the project, found the heap and permanent generations have been growing, not declining, the rate of recovery simply can not keep up the pace, needless to say, this is almost certain be a memory leak.
After jdk1.8: Implementation of the area called the yuan space. Permanent generation of Java that tune is very difficult. Metadata generation may be permanently with each Full GC
occurrence moves. And substituting the permanent set is difficult to determine the size of the space. Thus , java class decides to allocate the metadata in local memory, the maximum voxel space allocated space available to the system memory. In this way, we avoid the generation of a permanent set the size of the problem. However , in this case, once the memory leak occurs, you will take a lot of local memory. If you find that your project in the local memory usage is abnormally high. Ah, that's a memory leak.
How to troubleshoot
(1) by jps
id find java process.
(2) top -p [pid]
find the maximum memory usage reaches
(3) jstat -gccause pid 20000
20 seconds every output Full GC
result
(4) found that Full GC
too many times, is essentially a memory leak. Generate dump
documents, tool analyzes which object too much aid. The basic problem to be able to locate where.
Examples
On StackOverflow, there is a problem, as shown in FIG.
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.
That is, roughly, because the interview is requested in writing programs for a memory leak, then the question of who suddenly ignorant force, so many chiefs have given the answer.
A case
of this example from the "algorithm" (fourth edition) a book, I simplified a bit
class stack{
Object data[1000];
int top = 0; public void push(Object o){ data[top++] = o; } public Object pop(Object o){ return data[--top]; } }
When data pops up from the inside of the stack, data pointing to the array element has also been retained pointer. So even if you pop the stack is empty, these elements make up the memory will not be recovered.
The solution is
public Object pop(Object o){
Object result = data[--top];
data[top] = null;
return result; }
Case II
In fact, this is a bunch of examples, these examples reasons cause memory leaks are similar, that is, without closing the stream , specifically, it can be a file stream, socket stream, the stream database connections, etc.
, as follows, did not close the file stream
try {
BufferedReader br = new BufferedReader(new FileReader(inputFile));
...
...
} catch (Exception e) { e.printStacktrace(); }
As another example, did not close the connection
try {
Connection conn = ConnectionFactory.getConnection();
...
...
} catch (Exception e) {
e.printStacktrace();
}
The solution is. . . Ah, we should be able. . You say you will not transfer close()
methods.
Case III
before talking about this case, everyone ThreadLocal
in Tomcat
there is to know what caused memory leaks. However, I have to say about this leak, and ThreadLocal itself has little relationship, I looked at the official website of the example given, basically belong to improper use.
In Tomcat's official website, record the problem. The address is: https://wiki.apache.org/tomcat/MemoryLeakProtection
However, the official website of this example, it may be difficult to understand, we slight modifications.
public class HelloServlet extends HttpServlet{ private static final long serialVersionUID = 1L; static class LocalVariable { private Long[] a = new Long[1024 * 1024 * 100]; } final static ThreadLocal<LocalVariable> localVariable = new ThreadLocal<LocalVariable>(); @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { localVariable.set(new LocalVariable()); } }
Then look at the conf arranged at sever.xml
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="150" minSpareThreads="4"/>
The maximum thread pool threads 150, a minimum of four threads
in Tomcat Connector component responsible for receiving and processing the request, a request to each, it will take a thread to the thread pool.
In this visit servlet
, the ThreadLocal
variable which is added the new LocalVariable()
instance, but not remove
so the variables with the thread back to the thread pool. In addition to the many visits to servlet
the same thread may not work with the thread pool inside, which will lead to more work inside thread pool threads will be a memory leak.
In addition, servlet
the doGet
method of creating inside the new LocalVariable()
time of using webappclassloader
.
Then the
LocalVariable
object is not released -> LocalVariable.class
no release -> webappclassloader
no release -> webappclassloader
load all the classes have not been released, also caused a memory leak.
In addition, you eclipse
are doing a reload operation, working inside the thread pool thread is always present, and the thread inside the threadLocal
variable has not been cleaned up. And reload time, will build a new webappclassloader
, repeat the above steps. Multi-reload several times, on memory overflow.
But after Tomcat7.0, you do every time reload
, it will clean up the thread pool thread work threadLocals
variables. Therefore, this problem after tomcat7.0, does not exist.
ps:ThreadLocal
the use Tomcat
under service environment to note that not every web request Operating procedures ThreadLocal
are unique. ThreadLocal
What is not equal to the life cycle of a Request
life cycle. ThreadLocal
Tightly bound with thread object, since Tomcat
the use of thread pool threads are possible reuse situation.