Memory leaks Ninject瞬态范围+;范围处置+;垃圾收集&x2B;内存泄漏

Memory leaks Ninject瞬态范围+;范围处置+;垃圾收集&x2B;内存泄漏,memory-leaks,garbage-collection,asp.net-web-api,ninject,Memory Leaks,Garbage Collection,Asp.net Web Api,Ninject,我是新手(我还在学习),如果你们这些绝地大师能帮我解决我的问题和顾虑,我将不胜感激 我想使用Ninject,我有下面的代码,我想知道我的对象是否会得到正确的处理和垃圾收集 对于Ninject的默认瞬态作用域,我读到“生命周期不由内核管理(作用域对象为null),永远不会被释放。” 如果我想在生产中使用我的代码,特别是当我得到大量对我的WebApi(POST)的并发调用时,它会导致内存泄漏等问题吗 在这种情况下,Ninject的对象范围最好使用什么 顺便问一下,如果我没有像“kernel.Bind

我是新手(我还在学习),如果你们这些绝地大师能帮我解决我的问题和顾虑,我将不胜感激

我想使用Ninject,我有下面的代码,我想知道我的对象是否会得到正确的处理和垃圾收集

对于Ninject的默认瞬态作用域,我读到“生命周期不由内核管理(作用域对象为null),永远不会被释放。”

如果我想在生产中使用我的代码,特别是当我得到大量对我的WebApi(POST)的并发调用时,它会导致内存泄漏等问题吗

在这种情况下,Ninject的对象范围最好使用什么

顺便问一下,如果我没有像“kernel.Bind().To();”那样指定对象范围,它会默认为TransientScope吗

public class VehicleClassRepository : IVehicleClassRepository
{
    SomeDataContext context = new SomeDataContext();

    public IQueryable<VehicleClass> All
    {
        get { return context.VehicleClasses; }
    }

    public IQueryable<VehicleClass> AllIncluding(params Expression<Func<VehicleClass, object>>[] includeProperties)
    {
        IQueryable<VehicleClass> query = context.VehicleClasses;
        foreach (var includeProperty in includeProperties) {
            query = query.Include(includeProperty);
        }
        return query;
    }

    public VehicleClass Find(int id)
    {
        return context.VehicleClasses.Find(id);
    }

    public void InsertOrUpdate(VehicleClass vehicleclass)
    {
        if (vehicleclass.VehicleClassId == default(int)) {
            // New entity
            context.VehicleClasses.Add(vehicleclass);
        } else {
            // Existing entity
            context.Entry(vehicleclass).State = EntityState.Modified;
        }
    }

    public void Delete(int id)
    {
        var vehicleclass = context.VehicleClasses.Find(id);
        context.VehicleClasses.Remove(vehicleclass);
    }

    public void Save()
    {
        context.SaveChanges();
    }

    public void Dispose() 
    {
        context.Dispose();
    }
}

public interface IVehicleClassRepository : IDisposable
{
    IQueryable<VehicleClass> All { get; }
    IQueryable<VehicleClass> AllIncluding(params Expression<Func<VehicleClass, object>>[] includeProperties);
    VehicleClass Find(int id);
    void InsertOrUpdate(VehicleClass vehicleclass);
    void Delete(int id);
    void Save();
}
迟交的答案(将近2年),但万一其他人读到这

尽管垃圾收集器最终会处理您的VehicleClassRepository实例,但在此之前您很可能会遇到问题

您的数据上下文可能会保留一个开放的数据库连接,直到它被释放。数据库连接可能来自数据库连接池

在CLR结束垃圾收集这些请求(这也会处理它们)之前很久,传入的请求在试图获得db连接时就被阻塞了,但是没有可用的请求

我遇到过这种行为,并从中学到了很多。因此,VehicleClassRepository应该在依赖范围内确定范围,以便您每次调用都能得到一个,更重要的是,它将在调用完成后立即得到处理。

延迟应答(近2年),但万一其他人读到这篇文章

尽管垃圾收集器最终会处理您的VehicleClassRepository实例,但在此之前您很可能会遇到问题

您的数据上下文可能会保留一个开放的数据库连接,直到它被释放。数据库连接可能来自数据库连接池

在CLR结束垃圾收集这些请求(这也会处理它们)之前很久,传入的请求在试图获得db连接时就被阻塞了,但是没有可用的请求


我遇到过这种行为,并从中学到了很多。因此,VehicleClassRepository应该在依赖范围内进行作用域划分,以便每次调用都能得到一个作用域,更重要的是,调用完成后,它会立即被释放。

是的,如果不指定作用域,它默认为暂时作用域。暂时作用域意味着ninject不保留对所创建对象的引用。只要你不再保留对它的引用,它就会被GC收集到垃圾。BatteryBackupUnit:谢谢你的澄清。。。如果它没有保留对已创建对象的引用。。。我上面的代码应该不会被内存泄漏?使用InRequestScope会更好吗?是的,除非您保持引用的时间比需要的时间长,否则瞬态作用域意味着不会出现内存泄漏。关于InRequestScope:您只需要它(或任何其他作用域,如InSingleton、NamedScope、ParentScope…)如果希望将同一个ISomething实例注入属于同一对象的2+个对象中。和/或如果您希望ninject管理其生命周期(即处置它)。InRequestScope意味着一旦请求范围被释放(请求结束),Ninject将调用ISomething.Dispose()。我对Web MVC和InRequestScope扩展不太熟悉,因此我无法回答更多关于这方面的具体问题。是的,如果不指定范围,它将默认为临时范围。暂时作用域意味着ninject不保留对所创建对象的引用。只要你不再保留对它的引用,它就会被GC收集到垃圾。BatteryBackupUnit:谢谢你的澄清。。。如果它没有保留对已创建对象的引用。。。我上面的代码应该不会被内存泄漏?使用InRequestScope会更好吗?是的,除非您保持引用的时间比需要的时间长,否则瞬态作用域意味着不会出现内存泄漏。关于InRequestScope:您只需要它(或任何其他作用域,如InSingleton、NamedScope、ParentScope…)如果希望将同一个ISomething实例注入属于同一对象的2+个对象中。和/或如果您希望ninject管理其生命周期(即处置它)。InRequestScope意味着一旦请求范围被释放(请求结束),Ninject将调用ISomething.Dispose()。我对Web MVC和InRequestScope扩展不太熟悉,因此我无法回答更多关于这方面的具体问题。
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IVehicleClassRepository>().To<VehicleClassRepository>();
    }   
public HttpResponseMessage Post(VehicleClass value)
{
        if (value == null)
        {
            return new HttpResponseMessage(HttpStatusCode.BadRequest);
        }
        else
        {
            vehicleclassRepository.InsertOrUpdate(value);
            vehicleclassRepository.Save();
            return new HttpResponseMessage(HttpStatusCode.Created);
        }
}