Log4j 2 无垃圾模式

来自姬鸿昌的知识库
跳到导航 跳到搜索

https://www.bilibili.com/video/BV1iJ411H74S?p=35

Log4j 2 的性能

Log4j 2 最牛的地方在于异步输出日志时的性能表现,Log4j 2 在多线程的环境下吞吐量与 Log4j 和 Logback 的比较如下图。

下图中比较中 Log4j 2 有三种模式:

  1. 全局使用异步模式;
  2. 部分 Logger 采用异步模式;
  3. 异步 Appender
生成缩略图出错:无法将缩略图保存到目标地点

可以看出在前两种模式下,Log4j 2 的性能较之 Log4j 和 Logback 有很大的优势。


无垃圾记录

垃圾收集暂停是延迟峰值的常见原因,并且对于许多系统而言,花费大量精力来控制这些暂停。

许多日志库(包括以前版本的 Log4j)在稳态日志记录期间分配临时对象,如日志事件对象,字符串,字符数组,字节数组等。

这会对垃圾收集器造成压力并增加 GC 暂停发生的频率。

从版本 2.6 开始,默认情况下 Log4j 以“无垃圾”模式运行,其中重用对象和缓冲区,并且尽可能不分配临时对象。

还有一个“低垃圾”模式,它不是完全无垃圾,但不使用 ThreadLocal 字段。

Log4j 2.6 中的无垃圾日志记录部分通过重用 ThreadLocal 字段中的对象来实现,部分通过在将文本转换为字节时重用缓冲区来实现。


Log4j 2.5: memory allocation rate 809 MB/sec, 141 minor collections.

生成缩略图出错:无法将缩略图保存到目标地点

“Allocation Rate for TLABs”每秒进行 809.58MB 的内存分配;Allocation Rate for TLABs

“Garbage Collections”进行了 141 次 minor collection(次要垃圾回收/小型垃圾回收,区别于 Full GC)


Log4j 2.6 did not allocate temporary objects: 0 (zero) garbage collections.

生成缩略图出错:无法将缩略图保存到目标地点


禁用无垃圾日志

https://logging.apache.org/log4j/2.x/manual/garbagefree.html#disabling-garbage-free-logging

有两个独立的系统属性可用于手动控制Log4j使用的机制,以避免创建临时对象:

  • log4j2.enableThreadlocals - 如果设置为"true"(非Web应用程序的默认设置),则对象存储在 ThreadLocal 字段中并被重用,否则为每个日志事件创建新的对象。
  • log4j2.enableDirectEncoders - 如果设置为"true"(默认设置),则日志事件将被转换为文本,并将此文本转换为字节,而不会创建临时对象。注意:对于多线程应用程序,同步记录性能在此模式下可能会变差,因为在共享缓冲区上进行同步。如果您的应用程序是多线程的,并且记录性能很重要,请考虑使用异步记录器。

Log4j 2使用的无垃圾日志记录技术旨在避免创建临时对象,从而减少内存分配和垃圾回收。

例如,在Log4j 2中,可以使用 ThreadLocal 字段重用对象,而不是为每个日志事件创建新对象。

此外,Log4j 2中的编码器(encoder)将日志事件转换为文本,并将此文本转换为字节,而不是创建临时对象,以减少内存分配和垃圾回收。