簡體   English   中英

編程c#:Parallel.Foreach內存消耗管理

[英]Programming c#: Parallel.Foreach Memory Consumption Management

我想使用Parallel.Foreach機制來確保CPU密集型任務的CPU充分利用。 我一次從數據庫中查詢大量對象(每次迭代中只有一個對象,每個對象相當小),然后對該對象執行大量基於CPU的操作,然后將其保存回去。到數據庫。

我在數據模型側使用實體框架,並根據查詢的對象數量,為每次迭代創建一個新的上下文(這是為了限制內存消耗):

    foreach (var id in idlist)
    {
        using (var ctx = new Context())
        {
            var model = ctx.Models.First(x => x.Id == id);
            await model.GlobalRefresh(true); //CPU heavy operation.
            await model.SaveAsync(); //Additional CPU heavy operation.
            ctx.SaveChanges(); //Save the changes
        } //Dispose of the model and the context, to limit memory consumption
    }

這在同步實現中效果很好,因為在每次迭代之后,都會處理從數據庫查詢的模型和實體框架上下文。 因此,在此過程中我的內存消耗幾乎是恆定的,這非常好。 如果不以這種方式創建上下文,則會很快耗盡內存(500多個對象)。

當我按如下所示並行進行上述設置時,我的內存消耗飛速增長,因為似乎每次迭代的上下文在下一次迭代繼續之前就沒有釋放(並且我確實看到了預期的明顯更高的CPU利用率):

        Parallel.ForEach(idlist, async (id) =>
        {
            using (var ctx = new Context())
            {
                var model = ctx.Models.First(x => x.Id == id);
                await model.GlobalRefresh(true);
                await model.SaveAsync();
                ctx.SaveChanges();
            }
        });

從內存的角度來看,這並不一定是問題,只要所有模型對象都不會一次加載到內存中(這實際上是並行循環的整個要點,一次要加載多個)。 但是,是否有某種方法可以更好地管理此過程,例如在內存消耗達到75%時不創建其他任務,以避免內存不足異常?

TL; DR:可以在下次操作之前使用MemoryFailPoint檢查是否有足夠的內存。 Microsoft Docs 在這里有一個很好的例子。

我最近有一個類似的問題。 在檢查較舊應用程序的日志時,我注意到一些“內存不足異常”。 事實證明,開發人員引入了一些並行編程,以使應用程序更快。 因此,也許該應用程序運行速度更快,但現在消耗的內存速度更快,並且達到了32位應用程序內存限制 (約為2GB),然后出現了這些內存不足異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM