【问题标题】:Memory leak in web API 2.0 methodWeb API 2.0 方法中的内存泄漏
【发布时间】:2018-07-11 20:54:51
【问题描述】:

我们项目中有一个webAPI,很简单,但是执行后不会释放内存,每次执行都会增加使用的内存。

我使用 webAPI 2.0 和 MongoDB 作为后端服务器。

public class LogsController:ApiController
{
    BsonDocument __docs;
    IMongoDatabase __db;
    IMongoCollection<BsonDocument> __docsColl;
    [Route("api/Logs")]
    public async Task<int> Post(RequestData logs)
    {
        if (logs.Token == "I")
        {
            __db = new MongoClient(new MongoClientSettings
            {
                Server = new MongoServerAddress("serverIP", 27017),
                Credentials = new[] { MongoCredential.CreateCredential("database", "user name", "password") }
            }).GetDatabase("connect_database");

            __docs = new BsonDocument()
            {
                { "Customer",logs.Customer}
            };
            __docsColl = __db.GetCollection<BsonDocument>("InsertData");
            await __docsColl.InsertOneAsync(__docs);
        }
        logs = null;
        return 1;
    }

    protected override void Dispose(bool disposing)
    {
        __docs = null;
        __db = null;
        __docsColl = null;
        GC.SuppressFinalize(true);
        base.Dispose(disposing);
    }

}

我已经尝试了所有可能的解决方案,但到目前为止都没有运气。

【问题讨论】:

  • it is not release memory every time it will increase the memory 您是如何得出这些结论的?是否有可以发布的日志或执行结果?
  • 您不要在任何地方调用“Dispose”方法。
  • 声明3个全局变量有什么具体原因吗?它们是否在这个类中的任何地方使用,在 Post() 方法之外?
  • 由于 webAPI 实现了 IDisposable,所以它会在我使用调试检查的 webAPI 响应后自动调用,它会调用 Dispose 方法。
  • 移除 Dispose(),将属性移入 Post()。去掉“...= null”,报告结果

标签: c# asp.net-mvc-4 asp.net-web-api asp.net-web-api2 mongodb-.net-driver


【解决方案1】:

当使用 post 参数调用 webAPI 时,它将反序列化为我们用作参数的类。

进一步检查发现,当类内容为字符串数据类型时,它将使用内存,而不是在从 webAPI 返回响应后一次释放。

如果你真的需要内存,那么你必须重写 ApiController 的 Dispose 方法。

代码块应该是:

protected override void Dispose(bool disposing)
        {
            GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            base.Dispose(disposing);
        }

GC.Collect 不是推荐的方法,但是当您在参数中发布大量数据时,您必须快速使用它来释放内存。

【讨论】:

    【解决方案2】:

    LogsController 的构造函数中初始化MongoClient,而不是在Post 方法中。

    【讨论】:

    • IMongoClient 不是 IDisposable。所以它正确地清除了自己。如果它有内存泄漏......这个库创建者的真正问题。
    • @alerya 这很有趣......好吧,如果有内存泄漏,它几乎肯定与正在创建的 Mongo 对象或 BsonDocuments 之一有关。 IMongoDatabase 可能不是一次性的,但 MongoClient?也许界面需要更新什么的。确实很奇怪。在我好奇的时候标记问题。
    • @MichaelPuckettII 发现当我们将该数据作为应用程序/JSON 格式发布到 webAPI 时,它将使用内存,然后它不会清除该发布参数的内存。 MongoClient 内部没有任何问题,因为它是安全的。
    • @EbgTest 太棒了,感谢分享。您可以在主题中发布完整答案作为答案吗?您可以在 24 小时后将其标记为已回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-25
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 2013-03-16
    相关资源
    最近更新 更多