tomcat Memory Overflow Problem Resolution Experience

  • 2021-06-28 14:30:41
  • OfStack

A product version was submitted to testers for testing in the last 1 time, and the results were simply unexpected!

After a period of testing, the page got stuck, and the subconscious suspicion based on this phenomenon was that it was stuck in the database layer, then check the parameters related to the database connection. As expected, there were too many connections!When the number of database connections was resolved, this bug was supposed to have been solved, but...

Page stuck again after a period of testing!!!

Open Task Manager and find that tomcat has more than 1.5G memory and tomcat cannot be turned off!What is the cause?When I think about it, I think about one point that might cause tomcat memory to rise: multithreading. Then I flip through the code to find the configuration of the thread pool and find nothing suspicious.

Then first solve the problem that tomcat can't shut down, Baidu... Check the code... 10 minutes later found that the thread pool was not closed in the destroy method of tomcat listener (contextDestroyed). In this case, tomcat can't shut down because the thread pool can't be closed.

Change the code to:


public class InitListener implements ServletContextListener{
  private Logger logger = Logger.getLogger(InitListener.class);
  @Override
  public void contextInitialized(ServletContextEvent sce) {
    logger.info(" start-up tomcat");
  }
  @Override
  public void contextDestroyed(ServletContextEvent sce) {
    logger.info(" Close tomcat, Close Thread Pool ");
    ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
    ThreadPoolTaskExecutor myTaskExecutor = (ThreadPoolTaskExecutor) classPathXmlApplicationContext.getBean("myTaskExecutor");
    myTaskExecutor.shutdown();
  }
}

Okay, the problem tomcat can't turn off is solved.

Next, resolve the memory overflow (see the log first):

Looking at the log of tomcat, it is found that the page initializes the configuration file of the background interface Spring once every time it is called, that is, spring is reinjected once every time it is requested, and the memory consumed is not reclaimed!

Then I thought about when I would initialize the spring configuration file: when tomcat starts;When it comes out with the keyword new, that is

ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");

Then we searched for code globally and found it in the filter. Every time the interface came, new 1 objects would be found. What terrible code, I kept scolding myself for what I thought at that time!I will take this experience as a precaution and write it down to tell myself not to repeat similar problems in the future.


Related articles: