Reputation: 11
org.apache.log4j.Hierarchy contains a hashtable named ht that keeps growing and growing until we hit an OutOfMemoryError in our application server.
ht has several millions entries and I do not understand why.
Several categories are defined in the log4.properties, and i would expect to have entries in this hashtable ONCE for each class matching a category definition.
But each time a new instance of some class is created, a new logger is added in this hashtable .. As a consequence, we do not control its size and it grows until it completely saturates the JVM.
Any ideas ? Is there any configuration to avoid this behaviour ? Should we clear this ht regularly ?
Using jmap histo clearly shows this constant evolution ..
Upvotes: 1
Views: 1799
Reputation: 25380
Log4 retains a reference to every logger that it creates. Each logger has a unique name, and each call to get a logger for a particular name will return the same logger object. org.apache.log4j.Hierarchy.ht
contains the cache of previously created logger objects. This is normal and expected behavior for log4j.
The most common pattern is for each class to create its own logger, named after that class. In that case, the number of loggers would naturally be limited to the number of classes in your application that creates loggers.
An application could create loggers with other names, though. For example:
for (int ii = 0; ii < 100_000; ++ii) {
Logger logger = Logger.getLogger(String.valueOf(ii));
}
This admittedly contrived example creates a hundred thousand loggers named after the numbers 0 to 99,999. Log4j would store a copy of each logger in the ht
table, just in case you ran that code more than once.
The LogManager
class has a function getCurrentLoggers()
which returns an enumeration of the loggers that have been created. You could use this to find out what loggers are being created. Perhaps your application is using an unusual logger naming pattern to create special loggers, and it's ending up with a large number of loggers?
Upvotes: 1