Java Log4j2-寻找一个无垃圾且执行异步日志记录的最小示例
我试图构造一个使用log4j2的程序的最小示例,它既没有垃圾,又利用异步日志记录。我相信我已经遵循了他们文档中讨论的所有指导原则,但我无法获得零(稳态)分配率。这里所附的工作为每个日志消息分配了大约60个字节 有没有人举过这样的例子,或者,他们能看到我所做的错误 更新:要使用的解决方案阻止了自动装箱和相关分配。下面的代码已更新 代码:Java Log4j2-寻找一个无垃圾且执行异步日志记录的最小示例,java,garbage-collection,log4j2,Java,Garbage Collection,Log4j2,我试图构造一个使用log4j2的程序的最小示例,它既没有垃圾,又利用异步日志记录。我相信我已经遵循了他们文档中讨论的所有指导原则,但我无法获得零(稳态)分配率。这里所附的工作为每个日志消息分配了大约60个字节 有没有人举过这样的例子,或者,他们能看到我所做的错误 更新:要使用的解决方案阻止了自动装箱和相关分配。下面的代码已更新 代码: <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN">
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="File" fileName="/dev/null" append="false" immediateFlush="false" >
<PatternLayout pattern="%d %p %c{1.} [%t] %m %ex %map{} %n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
-Dlog4j2.garbagefreeThreadContextMap=true
-Dlog4j2.enableThreadlocals=true
-Dlog4j2.enableDirectEncoders=true
-Dlog4j2.asyncLoggerWaitStrategy=yield
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
公共类示例{
静态私有最终记录器Logger=LogManager.getLogger(Example.class);
公共静态void main(字符串[]args)引发异常{
int count=Integer.parseInt(args[0]);
gc();
睡眠(10000);
for(int i=0;i
Log4J2配置:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="File" fileName="/dev/null" append="false" immediateFlush="false" >
<PatternLayout pattern="%d %p %c{1.} [%t] %m %ex %map{} %n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
-Dlog4j2.garbagefreeThreadContextMap=true
-Dlog4j2.enableThreadlocals=true
-Dlog4j2.enableDirectEncoders=true
-Dlog4j2.asyncLoggerWaitStrategy=yield
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
解决方案是使用
Unbox.box()
手动装箱原语值。这阻止了自动装箱和相关的分配
上述问题中的代码已用正确的代码更新
更新:
在下面的代码中,我扩展了解决方案,以演示使用消息对象的无垃圾异步日志记录。确切地说,这意味着我可以将一条可重用的消息传递给记录器(因此这些对象没有分配),消息可以在没有任何额外分配的情况下更新,消息可以在不需要分配的情况下格式化,基础记录器将不做任何进一步的分配,并且将其交给异步记录器是安全的(它将在传递给logger.info()
的瞬间写入上下文,而不是在异步记录器最终找到它时)
我发布这个更新是因为我在网上找不到类似的东西
代码:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<File name="File" fileName="/dev/null" append="false" immediateFlush="false" >
<PatternLayout pattern="%d %p %c{1.} [%t] %m %ex %map{} %n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>
-Dlog4j2.garbagefreeThreadContextMap=true
-Dlog4j2.enableThreadlocals=true
-Dlog4j2.enableDirectEncoders=true
-Dlog4j2.asyncLoggerWaitStrategy=yield
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
public类扩展示例{
静态类ApplicationEvent{
长标识符;
字符串细节;
长时间戳;
公共ApplicationEvent初始化(长标识符、字符串详细信息、长时间戳){
this.identifier=标识符;
this.detail=细节;
this.timestamp=时间戳;
归还这个;
}
}
静态私有最终记录器Logger=LogManager.getLogger();
公共静态void main(字符串[]args)引发异常{
int count=Integer.parseInt(args[0]);
gc();
睡眠(10000);
最终ApplicationEvent事件=新建ApplicationEvent();
for(int i=0;i