使用log4j2免费分配日志记录
介紹
最近,我正在為一個(gè)客戶端工作,試圖為大型精心制作的Java系統(tǒng)消除一些GC暫停。 經(jīng)過分析后,我意識到大部分垃圾都是通過日志記錄產(chǎn)生的! 是否有一種簡單的方法來刪除所有分配? 原來有:)
我應(yīng)該使用哪個(gè)框架進(jìn)行GC免費(fèi)日志記錄?
讓我們將注意力轉(zhuǎn)向使用哪個(gè)日志記錄框架的古老問題。
通常的候選人是
- log4j2
- 登入
- java.util.logging
- slf4j(簡單)
并且除非您正在做一些超級時(shí)髦的事情,否則您可能不會(huì)認(rèn)為這會(huì)給您帶來很大的改變。
已經(jīng)進(jìn)行了許多比較性能的研究,如果您在超低等待時(shí)間的競技場中玩,那當(dāng)然很重要。 ( 請參閱對Java日志記錄框架進(jìn)行基準(zhǔn)測試 )
但是我擔(dān)心的是分配!
請參閱我之前關(guān)于分配的弊端的文章“性能優(yōu)化的第一條規(guī)則”。
在典型的系統(tǒng)中,所有分配的30%-50%可以記錄在日志中! 因此,即使大多數(shù)人不介意在一個(gè)框架中進(jìn)行日志記錄的時(shí)間比在另一個(gè)框架中花費(fèi)幾毫秒的時(shí)間,他們幾乎肯定會(huì)在乎日志框架所產(chǎn)生的垃圾導(dǎo)致的長時(shí)間GC暫停。
而且所有這些日志記錄分配都可以通過簡單的配置刪除。 從2.6開始的Log4J2是免費(fèi)分配的,因此沒有任何借口不利用它:)
讓我們看看它的作用
提出免分配索賠是一回事,但讓我們看看這在實(shí)踐中是否成立。
考慮下面的這個(gè)簡單的日志記錄代碼:請注意,我在代碼中使用了slf4j,因此只需更改配置即可在不同的日志記錄框架中運(yùn)行。 這樣做是個(gè)好主意,因?yàn)楸M管log4j2可能是目前最好的框架,但誰知道明天會(huì)帶來什么……
package test;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream;public class GCLogger {private final static Logger LOGGER = LoggerFactory.getLogger(GCLogger.class);public static void main(String[] args) throws InterruptedException {List<String> list = IntStream.range(0,(int)1e6).mapToObj(i->"" + i).collect(Collectors.toList());//Log 1 million lines in a loop sleeping 1 second between each iteration of the loop//to allow time to run Flight Recorder.for (int i = 0; i < 1000; i++) {list.forEach(s->LOGGER.info("Logging [{}]", s));Thread.sleep(1000);}} }使用log4j2運(yùn)行–無分配
如果我們使用以下Maven配置將程序配置為與log4j2一起運(yùn)行:
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.9.1</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.9.1</version> </dependency> <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.9.1</version> </dependency>我們使用此log4j2配置
xml version="1.0" encoding="UTF-8" ?><Configuration status="INFO"><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{HH:mm:ss:SSS} [%t] %-5level %logger[36] %msg%n"></PatternLayout></Console><File name="MyFile" fileName="all.log" immeadiateFlush="false" append="false"><PatternLayout pattern="%d{dd MMM yyyy HH:mm:ss,SSS} [%t] %-5level %logger[36] %msg%n"></PatternLayout></File></Appenders><Loggers><Root level="debug"><AppenderRef ref="MyFile"></AppenderRef></Root></Loggers> </Configuration>然后我們得到0分配!
我們可以通過在程序上運(yùn)行Flight Recorder來證明這一點(diǎn)(見下文):
唯一分配的內(nèi)存歸因于Flight Recorder(可以通過配置FR的方式來避免這種情況發(fā)生)。
使用登錄運(yùn)行
使用Logback嘗試完全相同。
使用此Maven配置
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version> </dependency>使用此注銷配置:
<configuration><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>myApp.log</file><encoder><pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern></encoder></appender><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%msg%n</pattern></encoder></appender><root level="debug"><appender-ref ref="FILE" /></root> </configuration>當(dāng)我們使用Flight Recorder運(yùn)行時(shí),我們會(huì)看到一個(gè)擁抱量分配!
但是有一點(diǎn)警告……。
您需要完全按照文檔中的指定使用log4j2配置,請參閱支持的布局 。 如果您甚至更改日期格式,則略微分配將再次猖ramp。
摘要
- 使用slf4j,以便您可以輕松更改日志記錄實(shí)現(xiàn)
- 使用log4j2避免分配
- 確保使用支持的格式來支持免費(fèi)分配日志記錄
翻譯自: https://www.javacodegeeks.com/2017/10/allocation-free-logging-log4j2.html
總結(jié)
以上是生活随笔為你收集整理的使用log4j2免费分配日志记录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 与Maven的集成测试
- 下一篇: 软件这样卸载才干净电脑如何彻底卸载软件