在静态与非静态上下文中创建 SLF4J 记录器的开销是多少?

2022-09-01 14:37:34

我一直使用以下模式来构造(SLF4J)记录器:

private static final Logger log = LoggerFactory.getLogger(MyClass.class);

到目前为止,这已经奏效了,但是我想知道在某个时候的上下文,以及是否需要始终传入具体类文本,而不仅仅是使用非静态记录器,例如static

private final Logger log = LoggerFactory.getLogger(getClass());

这基本上已经被问到(和回答)之前在这里为LOG4J

记录器是否应该是私有静态的

和这里

应该记录器总是最终的和静态的吗?

我意识到基本上是强制性的,所以我想知道在非静态环境中使用SLF4J的开销到底有多高。final

Q:

使用是否有任何显著的实际开销

private final Logger log = LoggerFactory.getLogger(getClass());

private static final Logger log = LoggerFactory.getLogger(MyClass.class);

普通(网络)应用程序中?(无需在此处“讨论”高端,重负载Web应用程序)


请注意,我最终计划使用CDI使用更好的方法来获取SLF4J记录器,例如

@Inject private final Logger log;

正如这里描述的那样,http://www.seamframework.org/Weld/PortableExtensionsPackage#H-TtLoggerttInjection,但我需要首先了解记录器缓存。

子问题:甚至可以使用吗?

@Inject private static final Logger log;

(老实说,只是从CDI开始)


答案 1

非静态(实例)记录器变量的开销可以忽略不计,除非发生许多实例化(例如 10000 个或更多)。这里的关键词可以忽略不计。如果实例化了许多 (>10000) 对象,则影响可能是可测量的,但仍然很低。

更具体地说,实例记录器将每个对象实例的内存占用量增加一个引用(64 位)。在CPU方面,成本是每个实例一个哈希查找,即在哈希表中查找相应记录器的成本(小)。同样,除非创建许多许多对象,否则这两种成本都应该可以忽略不计。

这个问题在SLF4J常见问题解答中也有讨论。


答案 2

我不确定使用LoggerFactory时的确切开销,但我怀疑它会影响您的应用程序性能。因此,只需根据需要使用静态或非静态即可。

使用@Inject的好处应该是什么?LoggerFactory已经从具体impl中提供和抽象。无论如何,它将比LoggerFactory慢得多。

当您使用@Inject时,语法会更加简洁。但想象一下,你在测试中使用了这个类。然后,您必须设置注入以获取日志记录。使用普通的LoggerFactory,它在测试中也可以很好地工作。如果java有一个通用的机制来@Inject它会很好地工作,但因为它是设置就更难了。


推荐