Spring Boot的項目在直接關閉Tomcat8後,Tomcat8報內存溢出的4個警告(目前解決兩個)

直接停止Tomcat8後提示的警告異常如下圖所示,共有四個警告	:

在這裏插入圖片描述

  •  從圖中可以看出,共有四個警告異常:
     第一個:數據庫鏈接未釋放,被強制反註冊
     第二個~第四個:應用關閉,但是線程未釋放,導致報出了可能會有內存溢出的警告
    

解決方法:
第一個:參考了網上諸多大神的博客,添加如下監聽器,可解決第一個數據庫鏈接未釋放問題,此解決方法在我的項目中可以起到作用;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;

@Configuration
public class UnregisterDataSourceListener implements ServletContextListener {

    Logger logger = LoggerFactory.getLogger(UnregisterDataSourceListener.class);

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // On Application Startup, please…

        // Usually I'll make a singleton in here, set up my pool, etc.
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
      // This manually deregisters JDBC driver, which prevents Tomcat 7 from complaining about memory leaks wrto this class
        Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
                logger.debug("deregistering jdbc driver:{}", driver);
            } catch (SQLException e) {
                e.printStackTrace();
                logger.debug("Error deregistering driver:{}", driver);
                logger.debug("Error message:{}", e.getMessage());
            }

        }
    }

}

第二個~第四個:
主要是由於我的項目中在啓動時需要加載企業微信的配置,獲取Token,故啓動了一個線程獲取,最後線程未被回收,修改了一個監聽器,改爲實現ServletContextListener後又減少了一個警告:

import com.supplychain.controller.wechat.TokenThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/**
 * token失效管理
 * @author Hangele
 * @since 2018-09-17
 */
@Configuration
public class InitAppIdAndSecret implements ServletContextListener {

    private static Logger logger = LoggerFactory.getLogger(InitAppIdAndSecret.class);

    public void contextInitialized(ServletContextEvent e) {
        logger.info("contextInitialized starting");
        // 啓動定時獲取access_token的線程,暫時先拿掉,調試微信時再開放。
        String os = System.getProperty("os.name");
        logger.info(" 當前操作系統環境爲:{}", os);
        if (os.toLowerCase().startsWith("win")) {
            logger.info("windows環境,access_token的線程不啓動");
        } else {
            logger.info("啓動定時獲取access_token的線程............");
            new Thread(new TokenThread()).start();
        }
        logger.info("contextInitialized ends");
    }

    public void contextDestroyed(ServletContextEvent e) {
        logger.info("contextDestroyed starting");
        System.gc();
        logger.info("contextDestroyed ends");
    }
}

在釋放上下文時,調用了GC但是好像並沒有起到作用,還是要另尋辦法,先記錄至此!

修改後,效果如下圖所示:
在這裏插入圖片描述

暫時去掉了兩個,線程未釋放目前還未解決,不知道GC啥時候會回收…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章