In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces "how to solve the memory leak caused by ThreadLocal in Tomcat". In the daily operation, I believe that many people have doubts about how to solve the memory leak caused by ThreadLocal in Tomcat. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubt of "how to solve the memory leak caused by ThreadLocal in Tomcat". Next, please follow the editor to study!
Define
First of all, let's talk about the definition, because a bunch of people don't understand the difference between a memory overflow and a memory leak.
Memory overflow (OutOfMemory): you only have ten dollars, but I asked you for a hundred dollars. I'm sorry, I don't have so much money. (can't afford it)
Memory leak (MemoryLeak): you have ten dollars and I'll ask you for one. But the shameless blogger won't give you your money back. (not returned)
Relationship: multiple memory leaks can lead to memory overflows. (the blogger shamelessly asks you for more money a few times, and you will have no money.)
Harm
Ok, have you ever encountered the situation that the java program is getting more and more stuck in the project?
Because of memory leaks, it will lead to frequent Full GC, and Full GC will cause the program to pause, and finally Crash. As a result, you will feel that your program is getting more and more stuck, and then you are despised by the product manager. By the way, the reason why we tune JVM is to reduce the emergence of Full GC.
I remember that I once had a good time when the project was just launched. Results with the accumulation of time, OutOfMemoryError: PermGen space was reported.
Speaking of this PermGen space, suddenly, a flood of force, gushing out of the body of the blogger, be sure to introduce this method area, but so far, after all, this is not talking about "jvm from entry to give up".
Method area: an area of runtime memory that can be shared by threads from the java virtual machine specification. It stores structural information for each class, such as the bytecode content of the runtime constant pool (Runtime Constant Pool), field and method data, constructors, and common methods.
What is mentioned above is the specification, and the implementation is different in different virtual machines, the most typical being PermGen space and Metaspace.
Before jdk1.8: the one that implements the method area is called permanent generation. Because a long time ago, java felt that classes were almost static and were rarely unloaded and recycled, they gave it a nickname for eternity. Therefore, if you find that heap and permanent generation are growing all the time in the project, there is no downward trend, and the rate of recycling can not keep up with the growth rate at all, needless to say, it is almost certain that it is a memory leak.
After jdk1.8: implement the metaspace of the method area. Java finds it difficult to tune the permanent generation. The metadata in the permanent generation may move with each Full GC occurrence. And it is difficult to determine the size of the space for the permanent generation. Therefore, java decides to allocate the metadata of the class to local memory, and the maximum available memory space for metaspace is the system available memory space. In this way, we avoid the problem of setting the permanent generation size. However, in this case, in the event of a memory leak, it will take up a lot of your local memory. If you find that the local memory usage in your project is unusually high. Well, that's the memory leak.
How to troubleshoot
(1) find the java process id through jps.
(2) through top-p [pid], it is found that the memory footprint reaches the maximum.
(3) jstat-gccause pid 20000 outputs Full GC results every 20 seconds
(4) it is found that there are too many times of Full GC, which is basically a memory leak. Generate dump files and analyze which objects are too many with the help of tools. Can basically pinpoint what the problem is.
Example
On stackoverflow, there is a problem, as shown below
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.
Roughly, because the interview needs to write a memory leak program by hand, and then the questioner is suddenly confused, so many bosses give answers one after another.
Case one
This example is from the book algorithm (fourth Edition). I simplified it a little 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 the data pops up from the stack, the data array retains a pointer to the element. Then even if you empty the stack pop, the memory occupied by these elements will not be reclaimed.
The solution is
Public Object pop (Object o) {Object result = data [--top]; data [top] = null; return result;}
Case two
This is actually a bunch of examples, and the causes of memory leaks are similar, that is, the stream is not closed, specifically, it can be file stream, socket stream, database connection flow, and so on.
The details are as follows: file stream is not closed.
Try {BufferedReader br = new BufferedReader (new FileReader (inputFile));...} catch (Exception e) {e.printStacktrace ();}
For example, the connection is not closed.
Try {Connection conn = ConnectionFactory.getConnection ();...} catch (Exception e) {e.printStacktrace ();}
The solution is. Well, everyone should. Dare you say you can't call the close () method.
Case three
Before we talk about this example, do you know anything about memory leaks caused by ThreadLocal in Tomcat? However, I would like to say that this leak problem has little to do with ThreadLocal itself. I took a look at the examples given on the official website, which are basically caused by improper use.
The problem was documented on Tomcat's website. Address: https://wiki.apache.org/tomcat/MemoryLeakProtection
However, the example of the official website may not be easy to understand, so we will make some changes.
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 = new ThreadLocal (); @ Override public void doGet (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {localVariable.set (new LocalVariable ());}}
Let's take a look at the sever.xml configuration under conf.
The thread pool has a maximum of 150 threads and a minimum of 4 threads.
The Connector component in Tomcat is responsible for receiving and processing requests, and each time a request comes, it goes to the thread pool to fetch a thread.
When accessing the servlet, an instance of new LocalVariable () is added to the ThreadLocal variable, but not remove, so the variable goes back to the thread pool with the thread. In addition, multiple visits to the servlet may not use the same thread in the worker thread pool, which can lead to memory leaks among multiple threads in the worker thread pool.
In addition, webappclassloader is used to create new LocalVariable () in servlet's doGet method.
that
The LocalVariable object is not released-> LocalVariable.class is not released-> webappclassloader is not released-> all classes loaded by webappclassloader are not released, causing a memory leak.
In addition, if you do a reload operation in eclipse, the thread in the working thread pool still exists all the time, and the threadLocal variable in the thread is not cleaned up. When you reload, a new webappclassloader will be built, repeating the above steps. If you reload a few more times, the memory will overflow.
However, after Tomcat7.0, every time you do reload, you will clean up the thread's threadLocals variable in the worker thread pool. Therefore, this problem will not exist after tomcat7.0.
The use of ps:ThreadLocal in the service environment of Tomcat should be noted that the ThreadLocal that the program runs every time a web request is not unique. The life cycle of ThreadLocal is not equal to the life cycle of a Request. ThreadLocal is tightly bound to thread objects, and threads may be reused because Tomcat uses thread pools.
At this point, the study on "how to solve the memory leak caused by ThreadLocal in Tomcat" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.