웹 응용 프로그램이 [Timer-0]라는 이름의 스레드를 시작한 것으로 보이지만 중지하지 못했습니다.
Spring Boot 1.5.9를 사용하고 있습니다.RELEASE + Java 8 + Tomcat 9 + Jersey + Oracle 및 내 앱은 다음과 같이 정의된 예약된 메서드를 가지고 있습니다.
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod = "shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
}
작업 클래스:
@Component
public class ClearCacheJob {
@Scheduled(fixedRate = 3600000, initialDelay = 10000)
public void clearErrorCodesCache() {
try {
logger.info("######## ClearCacheJob #########");
} catch (Exception e) {
logger.error("Exception in ClearCacheJob", e);
}
}
}
또한 다음과 같이 Oracle 드라이버를 등록 취소하는 클래스도 있습니다.
@WebListener
public class ContainerContextClosedHandler implements ServletContextListener {
private static final Logger logger = LoggerFactory.getLogger(ContainerContextClosedHandler.class);
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("######### contextInitialized #########");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("######### contextDestroyed #########");
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
logger.info(String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
logger.info(String.format("Error deregistering driver %s", driver), e);
}
}
}
}
Tomcat을 정지하면 다음 오류가 나타납니다.
WARNING [Thread-11] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [hai]
appears to have started a thread named [Timer-0] but has failed to stop it.
This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Unknown Source)
java.util.TimerThread.mainLoop(Unknown Source)
java.util.TimerThread.run(Unknown Source)
이 에러가 발생하는 이유와 수정 방법은 무엇입니까?
이 문제의 근본 원인 분석과 함께 몇 가지 해결책을 공유하고 싶습니다.
Oracle 사용자용
솔루션 #1
는 Tomcat의 해야 합니다./lib
. 저도 이 됐어요.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
주의: Oracle 드라이버는 그대로 두겠습니다./WEB-INF/lib
더입니니다다
솔루션 #2
진짜 해킹은 잠꼬대로 할 수 있다.
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("######### contextDestroyed #########");
Enumeration<Driver> drivers = DriverManager.getDrivers();
while (drivers.hasMoreElements()) {
Driver driver = drivers.nextElement();
try {
DriverManager.deregisterDriver(driver);
logger.info(String.format("deregistering jdbc driver: %s", driver));
} catch (SQLException e) {
logger.info(String.format("Error deregistering driver %s", driver), e);
}
}
try { Thread.sleep(2000L); } catch (Exception e) {} // Use this thread sleep
}
리소스 링크: "Tomcat은 [중단된 연결 정리 스레드]를 중지할 수 없습니다."에 대한 해결 방법
솔루션 #3
스베틀린 자레브는 걱정할 것 없다고 말했다.이것은 Tomcat의 표준 메시지입니다.그는 다음과 같은 근본 원인 분석을 했다.
이 문제는 응용 프로그램이 ScheduledExecutor를 시작하고(다른 스레드/TheadPool에서는 이 문제가 발생함) contextDestroyed에서 종료되지 않았을 때 발생합니다.따라서 애플리케이션/서버 중지 시 스레드를 종료하는지 확인하십시오.
리소스 링크: Tomcat8 메모리 누수
솔루션 #4
Oracle 사용자의 경우 이 게시물에는 다음과 같은 여러 답변이 있습니다.메모리 누수를 방지하기 위해 JDBC 드라이버가 강제로 등록 해제되었습니다.
MySQL 사용자의 경우
솔루션 #5
솔루션을 사용한 근본 원인 분석:
NonRegisteringDriver 클래스의 포기된 연결에 대한 정리 스레드가 정적 셧다운 방식으로 리팩터링되었습니다.메모리는 할당되었지만 해방되지 않았다.이 리크 문제가 발생했을 경우 를 사용하여 응용 프로그램에 컨텍스트청취자를 구현합니다.
AbandonedConnectionCleanupThread.shutdown()
contextDestroyed
★★★★★★ 。이 문제는 Tomcat 응용 프로그램서버에서 실행되고 있는 응용 프로그램에서 발견되었지만 다른 응용 프로그램서버에도 적용되었을 가능성이 있습니다.
예를 들어 다음과 같습니다.
@WebListener public class YourThreadsListener implements ServletContextListener { public void contextDestroyed(ServletContextEvent arg0) { try { AbandonedConnectionCleanupThread.shutdown(); } catch (InterruptedException e) { } } ... }
컨테이너가 주석을 지원하지 않는 경우 web.xml에 설명을 추가합니다.
<listener> <listener-class>user.package.YourThreadsListener</listener-class> </listener>
리소스 링크: https://docs.oracle.com/cd/E17952_01/connector-j-relnotes-en/news-5-1-23.html
ScheduleConfig
shutdownNow
shutdown
괴괴방방방방방방
@Configuration
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean(destroyMethod = "shutdownNow")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(100);
}
}
코드를 기반으로 몇 가지 테스트를 수행하고 온라인에서 조사한 결과 다음과 같은 결론을 얻었습니다.
걱정할 것 없다(링크).Tomcat 프로세스가 완료되고 메모리 누수가 남아 있지 않습니다.
해도...
AbandonedConnectionCleanupThread.shutdown()
같은 경고(링크)가 표시될 수 있습니다.는 전화할 때 합니다.
startup.sh
★★★★★★★★★★★★★★★★★」shutdown.sh
Warning이되지 않습니다 이클립스 톰캣★★★★★★★★★★★★의 방법
Executor
가 호출되고 있는 것 같습니다. 제테 the, 가가 the the the를.destroyMethod
실행자의 경우.봄맞이 콩
Executors.newScheduledThreadPool
것을ScheduledThreadPoolExecutor
아까 말씀드린 것처럼 파괴 방법이 있고 파괴되고 있습니다.이치노,★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.
new java.util.Timer
를 , , , ,라고 합니다.new TimerThread()
@Claudio Corsi입니다.
이클립스를 사용하는 경우 디버깅하려면 JDK 버전의 소스 코드를 첨부해야 합니다.클래스 선언을 열고(ctrl 키를 누른 상태에서 open declaration을 선택), "Attach Source Code" 버튼을 클릭합니다.동일한 버전을 다운로드했는지 확인하십시오.지퍼를 내릴 필요도 없습니다.Maven을 사용하고 있다면 다운로드 할 수 있도록 조금만 기다려 주세요.
다음 .java.util.Timer
이치노
편집: 참조 식별 후java.util.Timer
저장해놓고, 저장해놓고, , 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고, 저장해놓고cancel
destroy.context destroy.con
또, 다음의 에러에 대해서도 같은 문제가 발생하고 있습니다.
The web application [ROOT] appears to have started a thread named [cluster-ClusterId{value='5d29b78967e4ce07d9bb8705', description='null'}-localhost:27017] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
잠시 후 스프링 부트 어플리케이션의 모든 서브모듈에 대해 maven 설치를 하지 않았다는 것을 알게 되었습니다.따라서 다음과 같은 오류가 발생하는지 다시 한 번 확인합니다.
mvn clean install -U
프로젝트 내의 모든 서브모듈과 프로젝트 자체에도 적용됩니다.
근본 원인을 말하기는 어렵지만, 스레드명 [Timer-0]은 그것을 찾을 수 있는 실마리를 준다. java.util.Timer
class는 소스 코드에서 볼 수 있듯이 Timer-*와 같은 이름 패턴을 가진 스레드를 만듭니다.
public Timer() {
this("Timer-" + serialNumber());
}
클래스 경로에 있는 라이브러리가 타이머 스레드를 시작하지만 취소되지 않거나 이 스레드에서 작동하는 코드가 고착되었을 수 있습니다.
중단점을 둘 것을 제안할 수 있습니다.java.util.Timer
디버깅하여 어떤 태스크가 동작하고 있는지 확인합니다.근본 원인을 가리킬 수 있습니다.
언급URL : https://stackoverflow.com/questions/48254517/the-web-application-appears-to-have-started-a-thread-named-timer-0-but-has-fai
'programing' 카테고리의 다른 글
config()에 $location을 삽입할 수 없는 이유는 무엇입니까? (0) | 2023.03.26 |
---|---|
ToString 메서드에 대한 오버로드가 없습니다.일자를 캐스팅할 때 1개의 인수를 사용합니다. (0) | 2023.03.26 |
JSON 표준 - 부동 소수점 수 (0) | 2023.03.26 |
woocommerce 가게는 어디서 주문하나요? (0) | 2023.03.26 |
Subject와 Behavior Subject의 차이점은 무엇입니까? (0) | 2023.03.26 |