Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无状态REST API怎么会有内存泄漏?_C#_Memory Leaks_Asp.net Core Webapi - Fatal编程技术网

C# 无状态REST API怎么会有内存泄漏?

C# 无状态REST API怎么会有内存泄漏?,c#,memory-leaks,asp.net-core-webapi,C#,Memory Leaks,Asp.net Core Webapi,所以我有一个无状态Asp.Net核心RESTWeb API,它似乎有内存泄漏。。。这对我来说似乎很奇怪,但证据很有说服力 这是我的Azure门户的屏幕截图,显示RAM正在缓慢上升 现在我的API非常标准。。。积垢,大量的数据检索。。。没有太多疯狂的逻辑或任何东西,但它获得了大量的流量(平均每秒约17个请求)。最终,服务器到达我必须重新启动它的位置,以便释放内存 下面是一个典型的保存方法 同样,API是无状态的,所以我不会真正缓存或保留任何数据。。。做我该做的,把数据还给我 想法 [Ht

所以我有一个无状态Asp.Net核心RESTWeb API,它似乎有内存泄漏。。。这对我来说似乎很奇怪,但证据很有说服力

这是我的Azure门户的屏幕截图,显示RAM正在缓慢上升

现在我的API非常标准。。。积垢,大量的数据检索。。。没有太多疯狂的逻辑或任何东西,但它获得了大量的流量(平均每秒约17个请求)。最终,服务器到达我必须重新启动它的位置,以便释放内存

下面是一个典型的保存方法

同样,API是无状态的,所以我不会真正缓存或保留任何数据。。。做我该做的,把数据还给我

想法

    [HttpPost]
    public IActionResult Save([FromBody]QuizViewModel quiz)
    {
        if (ValidateAdmin() == null)
            return StatusCode(401);

        try
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            Quiz dbQuiz = null;

            if (quiz.ID == new Guid())
            {
                LogInfo("Saving new quiz: Name [" + quiz.Name + "]");

                // new 
                dbQuiz = new Quiz();
                dbQuiz.ID = Guid.NewGuid();
                dbQuiz.CreatorID = quiz.CreatorID;
                dbQuiz.CreateDate = DateTime.UtcNow;
                _quizRepository.Add(dbQuiz);
            }
            else
            {
                LogInfo("Updating quiz: ID [" + quiz.ID + "], Name: [" + quiz.Name + "]");
                // update
                dbQuiz = _quizRepository.GetSingle(x => x.ID == quiz.ID, y => y.Questions);
                dbQuiz.UpdateDate = DateTime.UtcNow;
                dbQuiz.UpdaterID = quiz.CreatorID;
            }

            _quizRepository.ManageQuestions(dbQuiz, quiz.Questions);

            dbQuiz.Name = quiz.Name;
            dbQuiz.LessonID = quiz.LessonID;
            dbQuiz.Instructions = quiz.Instructions;
            dbQuiz.ImagePath = quiz.ImagePath;
            dbQuiz.VideoPath = quiz.VideoPath;

            _quizRepository.Commit();

            quiz = Mapper.Map<Quiz, QuizViewModel>(dbQuiz);

            CreatedAtRouteResult result = CreatedAtRoute("Save", new { controller = "Quiz", ID = quiz.ID }, quiz);

            LogInfo("Quiz saved: ID [" + dbQuiz.ID + "]");
            return new OkObjectResult(result);
        }
        catch (Exception ex)
        {
            HandleError(ex);
            return BadRequest(ex);
        }
    }
[HttpPost]
公共IActionResult保存([FromBody]QuizViewModel测验)
{
if(ValidateAdmin()==null)
返回状态码(401);
尝试
{
如果(!ModelState.IsValid)
{
返回请求(ModelState);
}
测验dbquick=null;
如果(quick.ID==新Guid())
{
LogInfo(“保存新测验:名称[“+quick.Name+”]);
//新的
dbquick=新测验();
dbquick.ID=Guid.NewGuid();
dbquick.CreatorID=quick.CreatorID;
dbquick.CreateDate=DateTime.UtcNow;
_quizRepository.Add(dbquick);
}
其他的
{
LogInfo(“更新测验:ID[“+quick.ID+”],Name:[“+quick.Name+”]);
//更新
dbquick=\u quizRepository.GetSingle(x=>x.ID==quick.ID,y=>y.Questions);
dbquick.UpdateDate=DateTime.UtcNow;
dbquick.UpdaterID=quick.CreatorID;
}
_quizRepository.ManageQuestions(dbquick,quick.Questions);
dbquick.Name=quick.Name;
dbquick.LessonID=quick.LessonID;
dbquick.Instructions=quick.Instructions;
dbquick.ImagePath=quick.ImagePath;
dbquick.VideoPath=quick.VideoPath;
_quizRepository.Commit();
quick=Mapper.Map(dbquick);
CreatedAtRouteResult=CreatedAtRoute(“保存”,新建{controller=“quick”,ID=quick.ID},quick);
LogInfo(“保存的测验:ID[“+dbquick.ID+”]);
返回新的OkObjectResult(结果);
}
捕获(例外情况除外)
{
HandleError(ex);
返回请求(ex);
}
}

好的。。。所以,万一将来有人碰到这个。。。内存链接原来是一个配置问题。我太频繁地实例化配置对象,它们没有被释放

最终的解决方案是为配置创建一个单例。您可以在此处看到解决方案:


您不能确定这是内存泄漏,垃圾收集器可以决定不删除具有足够资源的对象。在每次返回之前,Ad a
GC.Collect()
,然后再次执行测试。此外,除非发布完整的api,否则无法确定是否存在内存泄漏,因为您只显示api中的一个函数。程序最终会崩溃还是引发异常?你能创建一个转储文件并检查什么正在使用所有内存吗?从您的屏幕截图上看,它看起来并没有显著增加。无状态指的是客户端/服务器之间的请求和响应,而不是“服务器永远不会保留任何内容”。如果您有DI(这是因为它是webapi),并且DI持有对从请求返回的对象的引用,那么它可能会在内存中累积,即使应用程序仍然是“无状态”的。正如@Gusman所说,要从一小段代码中确定泄漏的位置并不容易。我想你们都不会想要我的完整API:)我包含这段代码只是想了解一下我们调用的类型@xela是的,最终服务器将耗尽内存并崩溃。。。大约需要一天的时间。数据转储是个好主意。我会这样做,然后向你汇报。谢谢