.NET JIT Code Cache утечка? - PullRequest
       13

.NET JIT Code Cache утечка?

14 голосов
/ 25 февраля 2010

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

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

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

[Update]

Тем временем мы провели еще один анализ и в качестве вероятного подозрения использовали 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 на предварительно скомпилированный, проблема, похоже, исчезнет.

Ответы [ 2 ]

1 голос
/ 13 марта 2010

Используйте 'singleton' DataContext, вместо того, чтобы воссоздавать его все время в цикле.

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

Обновление:

Эта проблема должна быть исправлена ​​в .NET 4, поскольку она поддерживает динамические сборки GC'able.

0 голосов
/ 10 марта 2010

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

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