programing

Tomcat에서 메모리 누수가 발생할 가능성이 매우 높은가요?

stoneblock 2023. 7. 28. 21:45

Tomcat에서 메모리 누수가 발생할 가능성이 매우 높은가요?

다른 외부 오픈 소스와 함께 작동하도록 Tomcat을 구성했습니다.

그러나 Tomcat이 몇 분 동안 실행되면 다음과 같은 메시지가 표시됩니다.

심각: 웹 응용 프로그램 [/MyProject]에서 [java.lang] 유형의 키를 가진 ThreadLocal을 만들었습니다.ThreadLocal](값 [java.lang].ThreadLocal@1b3f02f]) 및 유형 [org.apache.axis] 값.MessageContext](값 [org.apache.axis].MessageContext@5dbd4e])을(를) 제거했지만 웹 응용 프로그램이 중지되었을 때 제거하지 못했습니다.이 경우 메모리 누수가 발생할 가능성이 매우 높습니다.

무엇이 원인이 될 수 있습니까?

어디를 봐야 합니까?톰캣에 대한 데이터 풀링일 수 있습니까?

톰캣의 스레드는 무슨 뜻입니까?

편집됨

여기 제 모든 흔적이 있습니다.응용 프로그램이 실행 중인 동안 컨텍스트를 다시 로드하는 것 같습니다. 이유를 모르겠습니다!

Mar 13, 2011 10:56:12 PM org.apache.catalina.core.StandardContext reload
INFO: Reloading this Context has started
Mar 13, 2011 10:56:12 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated
Mar 13, 2011 10:56:13 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated
Mar 13, 2011 10:56:14 PM org.apache.catalina.core.StandardWrapper unload
INFO: Waiting for 1 instance(s) to be deallocated
Mar 13, 2011 10:56:14 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/MyProject] registered the JBDC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc
SEVERE: The web application [/MyProject] registered the JBDC driver [oracle.jdbc.driver.OracleDriver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioSocketAcceptor-1] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-1] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-4] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [bitronix-disk-force-batcher] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [bitronix-scheduler] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] is still processing a request that has yet to finish. This is very likely to create a memory leak. You can control the time allowed for requests to finish by using the unloadDelay attribute of the standard Context implementation.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-7] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/MyProject] appears to have started a thread named [NioProcessor-2] but has failed to stop it. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@1b5a8e1]) and a value of type [org.mvel2.debug.DebuggerContext] (value [org.mvel2.debug.DebuggerContext@16259fd]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [org.apache.axis.utils.XMLUtils.ThreadLocalDocumentBuilder] (value [org.apache.axis.utils.XMLUtils$ThreadLocalDocumentBuilder@84b0b4]) and a value of type [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl] (value [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl@16d2cfa]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [null] (value [com.sun.faces.util.Util$1@16bbac9]) and a value of type [java.util.HashMap] (value [{com.sun.faces.patternCache={ = }}]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@1b3f02f]) and a value of type [org.apache.axis.MessageContext] (value [org.apache.axis.MessageContext@5dbd4e]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [org.apache.axis.utils.XMLUtils.ThreadLocalDocumentBuilder] (value [org.apache.axis.utils.XMLUtils$ThreadLocalDocumentBuilder@84b0b4]) and a value of type [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl] (value [com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl@378584]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [Transactional resources]) and a value of type [java.util.HashMap] (value [{org.hibernate.impl.SessionFactoryImpl@ccc27b=org.springframework.orm.hibernate3.SessionHolder@4f6ada}]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 13, 2011 10:56:15 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [/MyProject] created a ThreadLocal with key of type [null] (value [com.sun.faces.application.ApplicationAssociate$1@1f01fcf]) and a value of type [com.sun.faces.application.ApplicationAssociate] (value [com.sun.faces.application.ApplicationAssociate@1b85528]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
2011-03-13 22:57:27,734 ERROR (            ContextLoader.java:220)     - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class path resource [applicationContext-hibernate.xml]: Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [applicationContext-hibernate.xml]: Invocation of init method failed; nested exception is java.lang.OutOfMemoryError: Java heap space
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)

그 메시지는 실제로 꽤 분명합니다: 무언가가 만들어냅니다.ThreadLocal활자의 가치가 있는.org.apache.axis.MessageContext이것은 좋은 힌트입니다.이는 Apache Axis 프레임워크가 자체 정리를 잊어버렸거나 정리하지 못했다는 것을 의미합니다.예를 들어 Logback에서도 동일한 문제가 발생했습니다.별로 신경 쓰지 않으셔도 되지만, Axis 팀에 버그를 보고하는 것이 좋을 수도 있습니다.

이 오류를 는 Tomcat이 Tomcat을 보고하기 때문입니다.ThreadLocal쓰레드별로 생성됩니다. s는 HTTP " " 입니다. 프로그램이 남아 있습니다. "" "" "" "" "" "" "" "" ""ThreadLocal마찬가지로메모리 누수가 발생할 수 있습니다(org.apache.axis.MessageContext(언로드할 수 없음) 및 이러한 스레드가 나중에 다시 사용될 때 몇 가지 문제가 발생합니다.

자세한 내용은 http://wiki.apache.org/tomcat/MemoryLeakProtection 를 참조하십시오.

CDI @ApplicationScopedbean에서 @PreDestroy 메서드에 다음을 추가했으며 TomEE 1.6.0(tomcat 7.0.39, 현재)을 종료하면 스레드 로컬이 지워집니다.

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pf;

import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.lang.reflect.Field;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Administrator
 * 
 * google-gson issue # 402: Memory Leak in web application; comment # 25
 * https://code.google.com/p/google-gson/issues/detail?id=402
 */
public class ThreadLocalImmolater {

    final Logger logger = LoggerFactory.getLogger(ThreadLocalImmolater.class);

    Boolean debug;

    public ThreadLocalImmolater() {
        debug = true;
    }

    public Integer immolate() {
        int count = 0;
        try {
            final Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
            threadLocalsField.setAccessible(true);
            final Field inheritableThreadLocalsField = Thread.class.getDeclaredField("inheritableThreadLocals");
            inheritableThreadLocalsField.setAccessible(true);
            for (final Thread thread : Thread.getAllStackTraces().keySet()) {
                    count += clear(threadLocalsField.get(thread));
                    count += clear(inheritableThreadLocalsField.get(thread));
            }
            logger.info("immolated " + count + " values in ThreadLocals");
        } catch (Exception e) {
            throw new Error("ThreadLocalImmolater.immolate()", e);
        }
        return count;
    }

    private int clear(final Object threadLocalMap) throws Exception {
        if (threadLocalMap == null)
                return 0;
        int count = 0;
        final Field tableField = threadLocalMap.getClass().getDeclaredField("table");
        tableField.setAccessible(true);
        final Object table = tableField.get(threadLocalMap);
        for (int i = 0, length = Array.getLength(table); i < length; ++i) {
            final Object entry = Array.get(table, i);
            if (entry != null) {
                final Object threadLocal = ((WeakReference)entry).get();
                if (threadLocal != null) {
                    log(i, threadLocal);
                    Array.set(table, i, null);
                    ++count;
                }
            }
        }
        return count;
    }

    private void log(int i, final Object threadLocal) {
        if (!debug) {
            return;
        }
        if (threadLocal.getClass() != null &&
            threadLocal.getClass().getEnclosingClass() != null &&
            threadLocal.getClass().getEnclosingClass().getName() != null) {

            logger.info("threadLocalMap(" + i + "): " +
                        threadLocal.getClass().getEnclosingClass().getName());
        }
        else if (threadLocal.getClass() != null &&
                 threadLocal.getClass().getName() != null) {
            logger.info("threadLocalMap(" + i + "): " + threadLocal.getClass().getName());
        }
        else {
            logger.info("threadLocalMap(" + i + "): cannot identify threadlocal class name");
        }
    }

}

트랜잭션 리소스 키는 올바른 트랜잭션 없이 데이터베이스와 대화하는 것처럼 보입니다.트랜잭션 관리가 올바르게 구성되어 있고 @Transactional 주석에서 실행되지 않는 DAO에 대한 호출 경로가 존재하지 않는지 확인합니다.이 문제는 컨트롤러 수준에서 트랜잭션 관리를 구성했지만 타이머에서 DAO를 호출하거나 @PostConstruct 주석을 사용하는 경우에 쉽게 발생할 수 있습니다.여기 http://georgovassilis.blogspot.nl/2014/01/tomcat-spring-and-memory-leaks-when.html 에 적어놨어요.

편집: (또한?) v1.4.3으로 수정된 spring-data-jpa 버그인 것 같습니다."트랜잭션 리소스" 키를 설정하는 LockModeRepositoryPostProcessor의 spring-data-jpa 소스에서 찾아봤습니다.1.4.3에서는 키를 다시 지웁니다.

때로는 구성 변경과 관련이 있습니다.Tomncat 6.0.14에서 6.0.26으로 업그레이드했을 때 비슷한 것을 확인했습니다.여기 해결책이 있습니다. http://www.skill-guru.com/blog/2010/08/22/tomcat-6-0-26-shutdown-reports-a-web-application-created-a-threadlocal-threadlocal-has-been-forcibly-removed/

이 문제는 정리 작업에 처리기를 사용하지 않고 타사 솔루션을 사용할 때 발생합니다.저는 EhCache에서 이런 일이 발생했습니다.프로젝트에서 캐싱을 위해 EhCache를 사용했습니다.그리고 우리는 종종 로그에서 다음과 같은 오류를 보곤 했습니다.

 SEVERE: The web application [/products] appears to have started a thread named [products_default_cache_configuration] but has failed to stop it. This is very likely to create a memory leak.
Aug 07, 2017 11:08:36 AM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/products] appears to have started a thread named [Statistics Thread-products_default_cache_configuration-1] but has failed to stop it. This is very likely to create a memory leak.

또한 개발 중에 변경 사항을 반영하기 위해 백엔드 변경을 수행하고 애플리케이션을 여러 번 배포하는 동안 Tomcat이 Out Of Memory 오류로 인해 실패하는 경우가 종종 있었습니다.

이것이 우리가 한 해결책입니다.

<listener>
  <listener-class>
     net.sf.ehcache.constructs.web.ShutdownListener
  </listener-class>
</listener>

그래서 제가 말씀드리고 싶은 것은 당신이 사용하고 있는 타사 라이브러리의 문서를 확인하는 것입니다.그들은 셧다운 중에 스레드를 정리할 수 있는 몇 가지 메커니즘을 제공해야 합니다.응용 프로그램에서 사용해야 하는 항목입니다.그들이 제공하지 않는 한 휠을 다시 발명할 필요가 없습니다.최악의 경우에는 자신만의 구현을 제공하는 것입니다.

EHCache 종료에 대한 참조 http://www.ehcache.org/documentation/2.8/operations/shutdown.html

언급URL : https://stackoverflow.com/questions/5292349/is-this-very-likely-to-create-a-memory-leak-in-tomcat