Search code examples
nlogdotmemory

NLog: ObjectReflectionCache class always initializes a MruCache object with huge capacity


I develop a WPF application which uses NLog.

When I profile it using dotMemory I can see ~300k of Memory used by a Dictionary which NLogs creates during configuration.

I do not know what the ObjectReflectionCache and MruCache are used for an whether their memory will be freed at some time. Maybe someone can clarify the purpose of the classes and the huge capacity used for the Dictionary.

Thank you.

stacktrace how NLog creates Dictionary

memory usage of Dictionary

NLog version: 4.7.2

Platform: .NET Framework 4.6.1

Current NLog config

LoggingConfiguration config = new LoggingConfiguration();
DebuggerTarget debuggerTarget = new DebuggerTarget { Name = "vs", Layout = DebuggerLayout };
DebuggerLoggingRule = new LoggingRule(nlogLoggerNamePattern, debuggerTarget);
config.LoggingRules.Add(DebuggerLoggingRule);
LogManager.Configuration = config;

Solution

  • Taking my hat off for someone that cares about 300 KByte. Long time since I have been focusing on overhead of this size (But still important).

    From your screenshot that it is this collection:

    https://github.com/NLog/NLog/blob/29879ece25a7d2e47a148fc3736ec310aee29465/src/NLog/Internal/Reflection/ObjectReflectionCache.cs#L52

    The dictionary capacity is 10103 entries. Which is probably the prime number closest to 10000.

    I'm guessing the size of Tkey + TValue of the Dictionary is close to 30 bytes. This gives the total result of 300 KBytes though probably unused. Guess NLog could reduce its initial overhead by not allocating 300 KByte upfront.

    The dictionary is used for caching object-reflection for object-types logged for use in structured logging. Before NLog 4.7 the dictionary was only allocated when actually doing structured logging, but this changed with https://github.com/NLog/NLog/pull/3610

    Update Memory footprint has been reduced with NLog ver. 4.7.3