当前位置: 首页 > 知识库问答 >
问题:

关于log4j2内存泄漏,当我在Spring启动时引发异常

都飞跃
2023-03-14

环境:spring boot 1.5.9。发布spring-boot-starter-log4j2(是Log4j 2.7版本)

所有输出信息大小为9KB,包括所有spring boot输出

这是我的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启动并通过引发异常进行测试时,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内存泄漏的信息,有人能给我一些解决方法吗?非常感谢你!

共有1个答案

子车劲
2023-03-14
<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>
 类似资料:
  • 当关闭Tomcat时,我得到以下错误: 严重:web应用程序[App]创建了一个ThreadLocal,其键类型为[org.apache.logging.log4j.core.layout.PatternLayout$1](值为[org.apache.logging.log4j.core.layout.PatternLayout$1@14391AAF]),值类型为[java.lang.String

  • 我有一个潜在的内存泄漏在我的代码,我正在试图找到一个解决方案。我使用的是Android框架的spring。更具体的是 为了使一个即时装订。然而,当我进行内存分析时,我得到了以下结论: 由“Dalvik.System.PathClassLoader@0x43692B80”加载的1.628个“com.products.product”实例占用1.363.064(22,20%)字节。这些实例是从“jav

  • 在MAT工具中分析了堆转储后。泄漏嫌疑人说:“”加载的一个“java.util.TaskQueue”实例占用680,207,896(82.39%)字节。该实例由org.apache.tomcat.util.threads.taskThread@0xC1B52018 ajp-bio-8009-exec-243引用,由“java.net.urlClassLoader@0xCE67A9B8”加载。内存积

  • 我是android开发的新手,我刚刚从以下链接读到了Romain Guy的“避免android内存泄漏” http://www.curious-creature.org/2008/12/18/avoid-memory-leaks-on-android/ 然后我在我的android模拟器上用他著名的代码片段做了一个小测试 此代码应该在更改方向时泄漏第一个活动上下文。因此,我在emulator中运行了

  • 问题内容: 我认为我的android应用正在泄漏内存。我不是绝对确定这是问题所在。 应用程序打开时经常崩溃,并且logcat尝试加载位图图像时会显示“内存不足”异常。 崩溃后,我重新打开了该应用程序,它运行正常。Logcat会显示许多“ gc”,并且JIT表会不时地向上调整大小,而不会向下调整,直到应用程序因内存不足错误而崩溃。 这听起来像是内存泄漏吗?如果是这样,我该如何定位和关闭泄漏点。 这是

  • 问题内容: 我一直在追寻内存泄漏(由“ valgrind –leak-check = yes”报告),它似乎来自ALSA。这段代码已经存在于自由世界中一段时间​​了,所以我猜这是我做错的事情。 输出看起来像这样: 并继续一些页面 这是由于我在一个项目中使用ALSA并开始看到这种巨大的泄漏……或者至少是所说泄漏的报告。 所以问题是:是我,ALSA或valgrind在这里遇到问题吗? 问题答案: ht