ENV:
Spring 季靴子1.5.9.RELEASE
spring-boot-starter-log4j2(是Log4j 2.7版本)

All output information size is 9KB, including all spring boot output

这是我的log4j2.xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>

    <Properties>
        <Property name="pid">???</Property>


        <Property name="logPattern">%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:pid}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%xwEx</Property>


        <Property name="fileLogPattern">%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n\n</Property>


        <Property name="logPath">/data/server/tomcat/logs/bbPurchaseAgency</Property>

        <!-- for SizeBasedTriggeringPolicy, this is the problem, but I need file split function -->
        <Property name="fileSplitSize">2KB</Property>


        <Property name="fileSplitTime">1</Property>

        <Property name="maxSurviveTime">30d</Property>
    </Properties>

    <Appenders>
        <Console name="developLog" target="SYSTEM_OUT" follow="true">
            <PatternLayout charset="${encoding}" pattern="${logPattern}"/>
            <ThresholdFilter level="info" onMatch="accept" onMismatch="deny"/>
        </Console>


        <RollingFile name="infoFile" fileName="${logPath}/bbPurchaseAgency_info.log"
                     filePattern="${logPath}/bbPurchaseAgency_info_%d{yyyy-MM-dd}-%i.log">
            <PatternLayout charset="${encoding}" pattern="${fileLogPattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${fileSplitTime}"/>
                <SizeBasedTriggeringPolicy size="${fileSplitSize}"/>
            </Policies>
            <Filters>

                <!-- this filter will be print all information whatever level it is -->
                <ThresholdFilter level="info" onMatch="accept" onMismatch="deny"/>
                <ThresholdFilter level="error" onMatch="deny" onMismatch="neutral"/>
                <ThresholdFilter level="warn" onMatch="deny" onMismatch="neutral"/>
            </Filters>
            <DefaultRolloverStrategy>
                <Delete basePath="${logPath}" maxDepth="1">
                    <IfFileName glob="bbPurchaseAgency_info_%d{yyyy-MM-dd}-%i.log" />
                    <IfLastModified age="${maxSurviveTime}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>


        <RollingFile name="warnFile" fileName="${logPath}/bbPurchaseAgency_warn.log"
                     filePattern="${logPath}/bbPurchaseAgency_warn_%d{yyyy-MM-dd}-%i.log">
            <PatternLayout charset="${encoding}" pattern="${fileLogPattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${fileSplitTime}"/>
                <SizeBasedTriggeringPolicy size="${fileSplitSize}"/>
            </Policies>
            <Filters>

                <ThresholdFilter level="error" onMatch="deny" onMismatch="neutral"/>
                <ThresholdFilter level="warn" onMatch="accept" onMismatch="deny"/>
            </Filters>
            <DefaultRolloverStrategy>
                <Delete basePath="${logPath}" maxDepth="1">
                    <IfFileName glob="bbPurchaseAgency_warn_%d{yyyy-MM-dd}-%i.log" />
                    <IfLastModified age="${maxSurviveTime}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>


        <RollingFile name="errorFile" fileName="${logPath}/bbPurchaseAgency_error.log"
                     filePattern="${logPath}/bbPurchaseAgency_error_%d{yyyy-MM-dd}-%i.log">
            <PatternLayout charset="${encoding}" pattern="${fileLogPattern}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${fileSplitTime}"/>
                <SizeBasedTriggeringPolicy size="${fileSplitSize}"/>
            </Policies>
            <Filters>

                <ThresholdFilter level="error" onMatch="accept" onMismatch="deny"/>
            </Filters>
            <DefaultRolloverStrategy>
                <Delete basePath="${logPath}" maxDepth="1">
                    <IfFileName glob="bbPurchaseAgency_error_%d{yyyy-MM-dd}-%i.log" />
                    <IfLastModified age="${maxSurviveTime}"/>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>

    <Loggers>
        <AsyncLogger name="com.baibu.purchaseAgency" level="info" includeLocation="false">
            <AppenderRef ref="infoFile"/>
        </AsyncLogger>

        <AsyncLogger name="com.baibu.purchaseAgency" level="warn" includeLocation="true">
            <AppenderRef ref="warnFile"/>
        </AsyncLogger>

        <AsyncLogger name="com.baibu.purchaseAgency" level="error" includeLocation="true">
            <AppenderRef ref="errorFile"/>
        </AsyncLogger>

        <Root level="info">
            <AppenderRef ref="developLog"/>
            <AppenderRef ref="infoFile"/>
            <AppenderRef ref="warnFile"/>
            <AppenderRef ref="errorFile"/>
        </Root>
    </Loggers>
</Configuration>

所以,这是一个问题:

当我通过引发异常激活spring boot并进行测试时,log4j2会打印一些东西,并触发我设计的异常,然后Spring引导无法停止因为log4j2内存泄漏 .

这是测试代码:

@Value( "${spring.datasource.url}" )
    public void checkDataSource( String url ) {
        logger.warn( "warning url" );
        logger.error( "error url" );
        Integer.parseInt( url );  // I raise an exception when spring boot starting
    }

这是堆栈信息:

The web application [ROOT] appears to have started a thread named [Log4j2-TF-4-1a752144-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 sun.misc.Unsafe.park(Native Method)
 java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
 java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460)
 java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359)
 java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942)
 java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
 java.lang.Thread.run(Thread.java:745)

我运行其他测试,如关闭文件拆分功能(将fileSplitSize设置为512MB),或执行此操作:

@Value( "${spring.datasource.url}" )
    public void checkDataSource( String url ) {
    new Thread( new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep( 10 * 1000 );

            } catch ( InterruptedException e ) {
                e.printStackTrace();
            }

            System.exit( 0 );
        }
    } ).start();
}

没有什么事情发生,一切都很好,没有内存泄漏....

另外我在log4j2网站(http://logging.apache.org/log4j/2.x/manual/webapp.html)上看到了这个描述:

为避免出现问题,当包含log4j-web jar时,将自动禁用Log4j关闭挂钩 .

我做到了,但没有工作 .

Log4j2的gitHub没有问题板,网上有关于log4j2内存泄漏的信息很少,有人能给我一些解决这个问题的想法吗?非常感谢你!