Слишком много экземпляров Log4Net LogImpl - PullRequest
0 голосов
/ 28 мая 2018

Мы используем log4net для ведения журнала, и я анализирую дамп памяти.Мы обернули реализацию log4net в наш собственный класс с именем «TextLogger», который содержит 6601 экземпляр в куче, а 325882 экземпляров LogImpl.

Это кажется мне странным.Мы создаем регистраторы, которые живут недолго, поэтому я думаю, что вполне возможно, что они просто ждут сбора мусора, но я все еще нахожу разницу слишком большой, чтобы ее можно было объяснить неочищенным мусором.

Скопировано из windbg, где сначаластолбец - количество экземпляров, а второй столбец - общий размер в байтах. Наш класс-обёртка: 6601 211232 Logging.TextLogger

классы log4net:

325882 10428224 log4net.Repository.Hierarchy.LoggerKey

325882 20856448 log4net.Core.что могло бы сказать, что это нормально, или мы как-то должным образом не утилизируем наши реализации логгеров?

Я думаю, также возможно, что мы каким-то образом храним ссылки на логгеры, предотвращая их сборку мусора, но мы не имеем близко кгоТо же количество экземпляров других классов, которые могут иметь ссылку на регистратор.

РЕДАКТИРОВАТЬ: реализация TextLogger:

public class TextLogger
{
    private ILog m_Logger;
    private string m_UniqueId;

    static TextLogger()
    {
        var stream = File.OpenRead(@"log4net.config");
        log4net.Config.XmlConfigurator.Configure(stream);
    }

    public TextLogger(string name, object owner)
    {
        m_UniqueId = Guid.NewGuid().ToString("n").Substring(0, 6);
        if (false && owner != null)
        {
            m_Logger = log4net.LogManager.GetLogger(string.Format("{0}-{1}", m_UniqueId, name), owner.GetType());
        }
        else
        {
            m_Logger = log4net.LogManager.GetLogger(string.Format("{0}-{1}", m_UniqueId, name));
        }
    }

    public void Debug(string msg)
    {
        m_Logger.Debug(msg);
    }

    public void Error(string msg)
    {
        m_Logger.Error(msg);
    }

    public void Error(string msg, Exception exception)
    {
        m_Logger.Error($"{msg}, {exception.ToString().Replace(Environment.NewLine, "<br>")}");
    }
    public void Warn(string msg)
    {
        m_Logger.Warn(msg);
    }
}

1 Ответ

0 голосов
/ 28 мая 2018

Я вижу, что для каждого экземпляра TextLogger создается новый log4net.ILog с уникальным именем, основанным на Guid:

m_Logger = log4net.LogManager.GetLogger(string.Format("{0}-{1}", m_UniqueId, name));

ILog, перестроенный log4net.LogManager, остается «живым» на времяваше приложение.Это позволяет впоследствии получить тот же экземпляр ILog по его имени.

Поскольку все ваши экземпляры имеют уникальные имена, они здесь учитываются.

При использовании log4net типичной настройкой является использование статического регистратора для каждого компонента / класса, как показано ниже.Попробуйте преобразовать ваш код во что-то похожее.

class Foo
{
    private static ILog _logger = LogManager.Instance.GetLogger(typeof(Foo));

    public void DoSomething()
    {
        _logger.Info("Doing something"); 
    }
}

Эта концепция хорошо объяснена на сайте log4net .

...