池化对象 RecyclableMemoryStream 在 .netcore 中的使用
Microsoft.IO.RecyclableMemoryStream 是一個被設計為專門用于提高 Stream 操作的高性能類庫,意思很明顯,專用于取代 MemoryStream 而生,RecyclableMemoryStream 可以最大限度的避免 Stream 操作在 GC 上的 LOH (大對象堆)的分配和內存碎片,泄露等煩人的問題,這篇文章我們將會討論 Microsoft.IO.RecyclableMemoryStream 及如何在 .NET Core 應用程序中提升性能。
RecyclableMemoryStream 的價值
RecyclableMemoryStream 大體上提供了如下四點價值。
使用緩沖池避免 LOH 分配。
大大的減少生成到2代堆的可能,相對減少了 GC 回收時造成的線程停滯時間。
避免了內存碎片和內存泄漏。
提供了用于跟蹤和分析性能的度量值。
RecyclableMemoryStream 的原理
RecyclableMemoryStream 在2代堆上存儲了一個用于流的大型緩沖區,并能夠確保這個緩沖區在進程的生命周期內一直存在,這就確保了GC不會頻繁的出現全量回收,同時 RecyclableMemoryStreamManager 類維護了兩類緩沖池。
小型緩沖池 ?常用于讀寫操作,每一個小池子大小為 128k。
大型緩沖池 ? 常用于當有連續緩沖的場景下使用,每一個大池子大小為 1MB。
值得注意的是,大型緩沖池的擴容又分為 線性增長 和 指數型增長,可以看出內存可被高效的反復使用并且對調用者還是無感知的,這就是為什么 RecyclableMemoryStream 比 MemoryStream 更好更高效的原因。
當調用 GetBuffer() 方法時,小緩沖區將會轉換為一個大的連續緩沖區,如下代碼所示:
var?buffer?=?recyclableMemoryStreamManager.GetStream().GetBuffer();安裝 RecyclableMemoryStream
你可以通過 Nuget 可視化界面安裝 Microsoft.IO.RecyclableMemoryStream 或者通過 NuGet package manager console window 執行如下命令。
Install-Package?Microsoft.IO.RecyclableMemoryStream使用 RecyclableMemoryStream
安裝好之后,接下來我們通過 RecyclableMemoryStream 將數據寫入到 MemoryStream 中,值得注意的是,RecyclableMemoryStreamManager.GetStream() 方法返回的是 MemoryStream 實例。
class?Program{private?static?readonly?RecyclableMemoryStreamManager?recyclableMemoryStreamManager?=?new?RecyclableMemoryStreamManager();static?void?Main(string[]?args){string?data?=?"This?is?a?sample?text?message.";var?buffer?=?Encoding.ASCII.GetBytes(data);using?(var?memoryStream?=?recyclableMemoryStreamManager.GetStream()){memoryStream.Write(buffer,?0,?buffer.Length);}Console.ReadKey();}}上面的代碼還有一點要注意,我將 RecyclableMemoryStreamManager 靜態化了,意味著它只需要定義一次就ok了,還有一點你可以對 MemoryStream 進行標記,方便后續持續跟蹤,如下代碼所示:
using?(var?memoryStream?=?recyclableMemoryStreamManager.GetStream("High_Performance_Stream_Demo.Program.Main")){memoryStream.Write(buffer,?0,?buffer.Length);}對 MemoryStream Pool 精細化配置
如果你想對 MemoryStream Pool 做更精細化的配置,可以在 RecyclableMemoryStreamManager 實例上進行配置,如下代碼所示:
int?blockSize?=?1024; int?largeBufferMultiple?=?1024?*?1024; int?maximumBufferSize?=?16?*?largeBufferMultiple; int?maximumFreeLargePoolBytes?=?maximumBufferSize?*?4; int?maximumFreeSmallPoolBytes?=?250?*?blockSize; var?recyclableMemoryStreamManager?=?new?RecyclableMemoryStreamManager(blockSize,?largeBufferMultiple,?maximumBufferSize); recyclableMemoryStreamManager.AggressiveBufferReturn?=?true; recyclableMemoryStreamManager.GenerateCallStacks?=?true; recyclableMemoryStreamManager.MaximumFreeLargePoolBytes?=?maximumFreeLargePoolBytes; recyclableMemoryStreamManager.MaximumFreeSmallPoolBytes?=?maximumFreeSmallPoolBytes;RecyclableMemoryStream 最佳實踐
內存碎片會影響到程序的性能,而且LOH獨有的鏈式管理也非常容易產生內存碎片,下面是使用 RecyclableMemoryStream 應該遵循的一些經驗法則。
根據你的業務場景設置合適的 blockSize, largeBufferMultiple, maxBufferSize, MaximumFreeLargePoolBytes, MaximumFreeSmallPoolBytes 值。
當使用完 Stream 對象時一定要速速關閉。
永遠不要調用 ToArray() 方法。
盡可能避免調用 GetBuffer() 方法。
Microsoft.IO.RecyclableMemoryStream 是 MemoryStream 的池化對象,它技巧性的減少了 GC 的負載并減少了 LOH 的大對象分配,自然就提高了應用程序的性能,不僅避免了內存碎片和內存泄漏還提供了用于跟蹤性能的指標。
譯文鏈接:https://www.infoworld.com/article/3597060/how-to-use-recyclablememorystream-in-net-core.html
總結
以上是生活随笔為你收集整理的池化对象 RecyclableMemoryStream 在 .netcore 中的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core和json请求这
- 下一篇: 如何在C#中使用 ArrayPool,M