简体   繁体   中英

.NET JIT Code Cache leaking?

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.

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.

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM