EFcore多線程查詢,該怎么解決內存泄漏的問題


 昨天在園子里提了一個EFcore多線程查詢導致服務內存飆升的問題,現在依然還沒有找到解決辦法,今天把問題詳細的陳述一遍。

剛開始發現問題是公司一個服務的內存飈到了7個G,系統直接殺死了這個進程,后面發現問題是隨着高並發的訪問,里面的EFcore進行大量數據查詢,在訪問結束后內存沒有釋放干凈,內存不斷的堆積,服務直接就崩了。然后我在本地用例還原了這個過程,大致如下:

GRPC服務端:

(一開始懷疑是DatabaseContext注入的問題,用了AddScoped;AddTransient;后者直接用using都沒有解決問題,所以不是這個問題)

在GRPC里一個方法SayHello查詢一張表的數據(數據大概1w多)

public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
var d = efoscoreContext.Project.Where(w => w.ProjectId > 15).Select(s => new 
{

*******
}).ToList();
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}

客戶端:

每三秒調一次Grpc的SayHello方法,后面發現GRPC服務里確實釋放不完內存,隨着訪問的次數的增加,內存會堆積到一個很高的值,如果內存抗不住就崩了

while (true)
{
for (int i = 1; i < 40; i++)
{
reply = client.SayHello(new FirstGrpc.HelloRequest() { Name = "" });
}
Thread.Sleep(TimeSpan.FromSeconds(3));
}

過程會進行GC,但是還會剩下大量的內存沒GC完,而且會累積到很高。

后面思考,GRPC服務以線程池的方式響應請求,會不會是Efcore在多線程里出現了問題的原因

后面我用控制台做了一個測試,發現問題確實是這樣,Efocore在多線程查詢,線程結束后,內存並沒有回收完

多線程Efocore查詢用例:

先順序執行:

while (true)
{
for (int i = 1; i < 100; i++)
{
ProjectQuery()//執行efocore查詢
;
}
Thread.Sleep(TimeSpan.FromSeconds(5));
}

順序執行沒有任何問題,內存占用是很正常的也就一直100多M

多線程執行:

while (true)
{
for (int i = 1; i < 100; i++)
{
 var t = new Task(() => ProjectQuery()//執行efocore查詢
);
t.Start();
}
Thread.Sleep(TimeSpan.FromSeconds(5));
}

多線程執行一上來就飈到了2G,后面會剩下1.2g一直在那里,再后面就會1-4M的累積,累積


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM