Is this very likely to create a memory leak in Tomcat?

前端 未结 5 2161
日久生厌
日久生厌 2020-11-29 01:29

I configured tomcat to work with a different external open source.

However, after the tomcat is running for a few minutes I get:

SEVERE: The w

5条回答
  •  感情败类
    2020-11-29 01:47

    I added the following to @PreDestroy method in my CDI @ApplicationScoped bean, and when I shutdown TomEE 1.6.0 (tomcat7.0.39, as of today), it clears the thread locals.

    /*
     * 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");
            }
        }
    
    }
    

提交回复
热议问题