.NET утечка Кэша Кода JIT?

Нам записали серверный компонент в.Net 3.5. Это работает как сервис на Windows Server 2008 Standard Edition. Это работает отлично, но через какое-то время (дни) мы замечаем крупное замедление и увеличенный рабочий набор. Мы ожидали некоторую утечку памяти и использовали WinDBG/SOS для анализа дампов процесса. К сожалению, "куча" GC не показывает утечки, но мы заметили, что "куча" кода JIT выросла от 8 МБ после запуска больше чем к 1 ГБ после нескольких дней.

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

Основной вопрос состоит в том, если существует какая-либо техника для анализа дампа и проверки, куда вся эта "куча" Кода Хоста блоки, которые показывают в дампах WinDBG, прибывает из?

[Обновление]

Тем временем мы сделали еще некоторый анализ и имели Linq2SQL как вероятный подозреваемый, тем более, что мы не используем предварительно скомпилированные запросы. Следующий пример программы создает точно то же поведение, где все больше блоков "кучи" Кода Хоста создается со временем.

using System;
using System.Linq;
using System.Threading;

namespace LinqStressTest
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i < 100; ++ i)
                ThreadPool.QueueUserWorkItem(Worker);
            while(runs < 1000000)            
            {
                Thread.Sleep(5000);
            }
        }

        static void Worker(object state)
        {
            for (int i = 0; i < 50; ++i)
            {
                using (var ctx = new DataClasses1DataContext())
                {
                    long id = rnd.Next();
                    var x = ctx.AccountNucleusInfos.Where(an => an.Account.SimPlayers.First().Id == id).SingleOrDefault();
                }
            }
            var localruns = Interlocked.Add(ref runs, 1);
            System.Console.WriteLine("Action: " + localruns);
            ThreadPool.QueueUserWorkItem(Worker);
        }

        static Random rnd = new Random();
        static long runs = 0;
    }
}

Когда мы заменяем запрос Linq предварительно скомпилированным, проблема, кажется, исчезает.

14
задан user173674 27 February 2010 в 18:27
поделиться

2 ответа

Единственный способ, которым я знаю утечку памяти в .net, связан с обработкой событий, проверьте это:

  1. link1
  2. также, возьмите посмотрите на следующий вопрос: Как мне избежать утечки памяти с помощью LINQ-To-SQL?
  3. также загляните в профилировщик ANTS
  4. И, думали ли вы, что, возможно, в какой-то момент вы будет много запущенных потоков? что изначально потребляет много памяти?
0
ответ дан 1 December 2019 в 17:00
поделиться

Используйте «одноэлементный» DataContext вместо его воссоздания все время в петле.

Я уверен, что эффект будет таким же, как у скомпилированных запросов.

Обновление:

Эта проблема должна быть «исправлена» в .NET 4, так как он поддерживает динамические сборки с возможностью сборки мусора.

1
ответ дан 1 December 2019 в 17:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: