简体   繁体   中英

About log4j2 memory leak when I raise an exception at spring boot starting

env:
spring boot 1.5.9.RELEASE
spring-boot-starter-log4j2 ( Is Log4j 2.7 version )

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

And this is my log4j2.xml config:

<?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>

So, here is the question:

When I active spring boot and testing by raise an exception, log4j2 print something, and trigger an exception what i design, AND THEN spring boot can not stop because log4j2 memory leak.

This is the test code:

@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
    }

And this is stack info:

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)

And I run other test, like closing file split function( set fileSplitSize to 512MB ), or do this:

    @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();
}

Nothing happen, all good, no memory leak....

Also I see this description on log4j2 web site( http://logging.apache.org/log4j/2.x/manual/webapp.html ):

To avoid problems the Log4j shutdown hook will automatically be disabled when the log4j-web jar is included.

I did it, but not working.

Log4j2's gitHub has no issues plate, and there are little information about log4j2 memory leak on the web, can someone give me some idea to solve this ? THANK YOU VERY MUCH!

<context-param>
    <!-- auto-shutdown stops log4j when the web fragment unloads, but that
         is too early because it is before the listeners shut down. To 
         compensate, use a Log4jShutdownOnContextDestroyedListener and
         register it before any other listeners which means it will shut
         down *after* all other listeners. -->
    <param-name>isLog4jAutoShutdownDisabled</param-name>
    <param-value>true</param-value>
</context-param>    

<listener>
   <!-- ensure logging stops after other listeners by registering
        the shutdown listener first -->
    <listener-class>
       org.apache.logging.log4j.web.Log4jShutdownOnContextDestroyedListener
    </listener-class>
</listener>
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM