日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET Core 3.0之深入源码理解ObjectPool(一)

發布時間:2023/12/4 asp.net 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .NET Core 3.0之深入源码理解ObjectPool(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

寫在前面

對象池是一種比較常用的提高系統性能的軟件設計模式,它維護了一系列相關對象列表的容器對象,這些對象可以隨時重復使用,對象池節省了頻繁創建對象的開銷。

它使用取用/歸還的操作模式,并重復執行這些操作。如下圖所示:

本文將主要介紹對象池的基本概念、對象池的優勢及其工作機制,下一篇文檔將從源碼角度介紹.NET Core 3.0是如何實現對象池的。

另外本公眾號引入了一位來自臺灣技術社區的程序員作為運營者,在不涉及到政治的情況下,歡迎大家積極來撩。

對象池基礎

對象池的基本概念

對象池的核心概念是容器,其表示形式可以認為是列表。每當有新的對象創建請求進入時,都會通過從池中分配一個對象來滿足該請求。當我們需要獲取某個對象時,可以從池中獲取。既然有了對象池,那么也就很方便我們就很容易建立起對象的管理與追蹤了了。

對象池的優勢

我們知道一旦應用程序啟動并運行,內存使用就會受到系統所需對象的數量和大小的影響。

我們知道創建一個對象的實例,是需要消耗一定的系統資源,尤其是該對象的構造十分復雜的時候,再加上需要頻繁創建的時候,其實例化所消耗的資源更加昂貴。如果我們能有一種辦法減少這種昂貴的系統開銷,這對系統性能的提升是十分有幫助的。

對象池理念的出現,有助于我們解決復雜對象的重復創建所引發的資源開銷問題。對象存儲在某種類型的列表或者說數組中,我們可以和獲取數組中的子項一樣獲取已經存在在對象池中的對象。

對象池的最大優點是,它可以自主管理內部已經創建的對象,包括回收和重復使用對象。程序在使用完某個對象后,會將其發還至對象池,而不是在內存中銷毀他們。

對象池通過資源的分配,因而也就減少了應用程序所需的垃圾回收數量。這對于需要頻繁創建同一對象的功能來說,對象池最大程度地減少了系統資源的消耗。

簡單來說,對象池的設計目標就是要使對象可以得到重復使用,而不是被垃圾回收器回收。

對象池的工作機制

通常情況下,當客戶端程序需要某個對象時,對象池首先嘗試提供一個已經創建的對象。如果沒有可用的對象,則會創建一個新對象。這類似于一個GetOrAdd的操作。同時對象池中對象的數量就會減少,直到該對象已經使用完,那么它就會被放回到對象池池中以等待使用。這就是為什么對象池有助于重用性、并減少了在獲取對象時創建對象所涉及的開銷的原因。

另外,需要注意的是,只要池中至少有一個對象,該池就會一直保留在內存中。只要對象池還在,里面的對象也會一直存在。

當對象池用于并發操作時,需要確保對象池是線程安全的,而且其本身還要有很高的性能。

ConcurrentBag對象池解決方案

這個解決方案來自于MSDN,ConcurrentBag <T>用于存儲對象,因為它支持快速插入和刪除,尤其是在同一線程同時添加和刪除項目時。該示例可以進一步擴展為圍繞IProducerConsumerCollection <T>構建,該數據由bag數據結構實現,ConcurrentQueue <T>和ConcurrentStack <T>也是如此。

using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; namespace ObjectPoolExample { public class ObjectPool<T> { private ConcurrentBag<T> _objects; private Func<T> _objectGenerator; public ObjectPool(Func<T> objectGenerator) { if (objectGenerator == null) throw new ArgumentNullException("objectGenerator"); _objects = new ConcurrentBag<T>(); _objectGenerator = objectGenerator; } public T GetObject() { T item; if (_objects.TryTake(out item)) return item; return _objectGenerator(); } public void PutObject(T item) { _objects.Add(item); } } class Program { static void Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSource(); // Create an opportunity for the user to cancel. Task.Run(() => { if (Console.ReadKey().KeyChar == 'c' || Console.ReadKey().KeyChar == 'C') cts.Cancel(); }); ObjectPool<MyClass> pool = new ObjectPool<MyClass> (() => new MyClass()); // Create a high demand for MyClass objects. Parallel.For(0, 1000000, (i, loopState) => { MyClass mc = pool.GetObject(); Console.CursorLeft = 0; // This is the bottleneck in our application. All threads in this loop // must serialize their access to the static Console class. ####.####}", mc.GetValue(i)); pool.PutObject(mc); if (cts.Token.IsCancellationRequested) loopState.Stop(); }); Console.WriteLine("Press the Enter key to exit."); Console.ReadLine(); cts.Dispose(); } } // A toy class that requires some resources to create. // You can experiment here to measure the performance of the // object pool vs. ordinary instantiation. class MyClass { public int[] Nums {get; set;} public double GetValue(long i) { return Math.Sqrt(Nums[i]); } public MyClass() { Nums = new int[1000000]; Random rand = new Random(); for (int i = 0; i < Nums.Length; i++) Nums[i] = rand.Next(); } } }

參考鏈接:https://docs.microsoft.com/en-us/dotnet/standard/collections/thread-safe/how-to-create-an-object-pool

總結

以上是生活随笔為你收集整理的.NET Core 3.0之深入源码理解ObjectPool(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。