.NET JIT Code Cache leaking?

2019-03-12 17:06发布

We have a server component written in .Net 3.5. It runs as service on a Windows Server 2008 Standard Edition. It works great but after some time (days) we notice massive slowdowns and an increased working set. We expected some kind of memory leak and used WinDBG/SOS to analyze dumps of the process. Unfortunately the GC Heap doesn’t show any leak but we noticed that the JIT code heap has grown from 8MB after the start to more than 1GB after a few days.

We don’t use any dynamic code generation techniques by our own. We use Linq2SQL which is known for dynamic code generation but we don’t know if it can cause such a problem.

The main question is if there is any technique to analyze the dump and check where all this Host Code Heap blocks that are shown in the WinDBG dumps come from?

[Update]

In the mean time we did some more analysis and had Linq2SQL as probable suspect, especially since we do not use precompiled queries. The following example program creates exactly the same behaviour where more and more Host Code Heap blocks are created over time.

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;
    }
}

When we replace the Linq query with a precompiled one, the problem seems to disappear.

2条回答
ら.Afraid
2楼-- · 2019-03-12 17:31

The only way i know of memory leakage in .net is due to events handling, check this out:

  1. link1
  2. also, take a look at the following question:How do I avoid a memory leak with LINQ-To-SQL?
  3. also, take a look into ANTS profiler
  4. And, have you considered, that maybe, at some point you will have many many threads running? which will nativly consume lots of memory?
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-03-12 17:40

Use a 'singleton' DataContext, instead of recreating it all the time in the loop.

I'm sure the effect will be the same as compiled queries.

Update:

This issue is meant to be 'rectified' in .NET 4 as it supports GC'able dynamic assemblies.

查看更多
登录 后发表回答