Log4j 2 无垃圾模式
https://www.bilibili.com/video/BV1iJ411H74S?p=35
Log4j 2 的性能
Log4j 2 最牛的地方在于异步输出日志时的性能表现,Log4j 2 在多线程的环境下吞吐量与 Log4j 和 Logback 的比较如下图。
下图中比较中 Log4j 2 有三种模式:
- 全局使用异步模式;
- 部分 Logger 采用异步模式;
- 异步 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)将日志事件转换为文本,并将此文本转换为字节,而不是创建临时对象,以减少内存分配和垃圾回收。