Debuging memory leak VS2015. Massive native heap

2019-06-14 16:41发布

问题:

I am struggling with memory issue which I can definitely see but I don't know where and when exactly it's happening.

My managed heap size seems to be ok (100MB), but native heap size is starting to growing in unknown moment and it's still going until it will reach ~2GB and app is crashing.

My application is running many threads, and it's doing a lot of Db connection through EF 6 in many loops. That's why it's really hard for me to debug code just by looking to logs or putting break points.

I thought maybe I can see what's the issue by looking at memory but what only I can see it's that my native heap size is mostly filled by objects with size of 8,192 bytes. So I can see that problem is really happening but still have no clue why.

I am not sure if I am using 100% capabilities of Visual Studio memory profiler.
What I can see now is:

What else or more I can do to find the issue?

Maybe it's silly question but I am working on this problem for two days and I've almost reached my ideas limit.

I've went through Break points, logs, code analyze but I am still without any clue.

I will be grateful for any idea.

[EDIT] 15:11 2017/02/03

I was able to find code responsible for the leak, but it still has no sense for me. How it's possible that this code is causing massive memory leak?

The code is :

public class DbData : IDisposable
{
    private DBEntity db;

    public DbData()
    {
        db = new FruitDBEntity();
    }

    public Fruit AddFruitDefinition(Fruit fruit)
    {
        lock (thisLock)
        {
            var newFruit = db.Fruits.Where(f => f.FruitId     == fruit.FruitId)
                                    .Where(f => f.FruitName   == fruit.FruitName)
                                    .Where(f => f.FruitColor  == fruit.FruitColor)
                                    .FirstOrDefault();
            if (newFruit == null)
            {
                newFruit = db.Fruits.Add(fruit);
                db.SaveChanges();
            }
            return newFruit;
        }
    }
}

Class DbData is created every time I want to use method AddFruitDefinition():

using ( var data = new DbData() ) 
{
    data.AddFruitDefinition();
}

回答1:

First, you need at least two snapshots. As far as I can see (from image) you took only one snapshot.

What to do?

  1. Start application with profiler.

  2. Do usual steps and take snapshot.

  3. Repeat same steps which you did in step 2, and take another snapshot.
  4. Stop application. You should see 2 snapshots, click on 2ns snapshot and select Compare to #Snapshot 1. It might take some time to process results.
  5. You should be able to see few additional columns in report (Identifier, count, Size, Module, Count Diff. Size Diff. Last two columns are important. They tell which class used more/less memory second time.

To sum up... you need to figure out where is memory leak and to fix it. And you'll do it by comparing snapshots.