org.apache.log4j.Hierarchy 包含名为 ht 的哈希表,该哈希表在我们的应用程序服务器中遇到 OutOfMemoryError 之前一直在增长和增长
ht 有数百万条目,我不明白为什么。
在log4.properties中定义了几个类别,我希望在每个符合类别定义的类的哈希表中都有条目。
但是每次创建某个类的新实例时,都会在此哈希表中添加一个新的记录器。 因此,我们不控制它的大小,它会一直增长,直到它完全使JVM饱和。
有什么想法吗?是否有任何配置可以避免这种行为? 我们应该定期清除这个吗?
使用jmap histo清楚地显示了这种不断演变。
答案 0 :(得分:1)
Log4保留对其创建的每个记录器的引用。每个记录器都有一个唯一的名称,每次调用获取特定名称的记录器都将返回相同的记录器对象。 org.apache.log4j.Hierarchy.ht
包含先前创建的记录器对象的缓存。这是log4j的正常行为和预期行为。
最常见的模式是每个类创建自己的记录器,以该类命名。在这种情况下,记录器的数量自然会限制在应用程序中创建记录器的类的数量。
但是,应用程序可以创建具有其他名称的记录器。例如:
for (int ii = 0; ii < 100_000; ++ii) {
Logger logger = Logger.getLogger(String.valueOf(ii));
}
这个公认的例子创造了以数字0到99,999命名的十万个记录器。 Log4j会将每个记录器的副本存储在ht
表中,以防您多次运行该代码。
LogManager
类有一个函数getCurrentLoggers()
,它返回已创建的记录器的枚举。您可以使用它来查找正在创建的记录器。也许你的应用程序正在使用一种不寻常的记录器命名模式来创建特殊的记录器,并且最终会有大量的记录器?