池化对象 RecyclableMemoryStream 在 .netcore 中的使用
Microsoft.IO.RecyclableMemoryStream 是一個(gè)被設(shè)計(jì)為專門用于提高 Stream 操作的高性能類庫(kù),意思很明顯,專用于取代 MemoryStream 而生,RecyclableMemoryStream 可以最大限度的避免 Stream 操作在 GC 上的 LOH (大對(duì)象堆)的分配和內(nèi)存碎片,泄露等煩人的問題,這篇文章我們將會(huì)討論 Microsoft.IO.RecyclableMemoryStream 及如何在 .NET Core 應(yīng)用程序中提升性能。
RecyclableMemoryStream 的價(jià)值
RecyclableMemoryStream 大體上提供了如下四點(diǎn)價(jià)值。
使用緩沖池避免 LOH 分配。
大大的減少生成到2代堆的可能,相對(duì)減少了 GC 回收時(shí)造成的線程停滯時(shí)間。
避免了內(nèi)存碎片和內(nèi)存泄漏。
提供了用于跟蹤和分析性能的度量值。
RecyclableMemoryStream 的原理
RecyclableMemoryStream 在2代堆上存儲(chǔ)了一個(gè)用于流的大型緩沖區(qū),并能夠確保這個(gè)緩沖區(qū)在進(jìn)程的生命周期內(nèi)一直存在,這就確保了GC不會(huì)頻繁的出現(xiàn)全量回收,同時(shí) RecyclableMemoryStreamManager 類維護(hù)了兩類緩沖池。
小型緩沖池 ?常用于讀寫操作,每一個(gè)小池子大小為 128k。
大型緩沖池 ? 常用于當(dāng)有連續(xù)緩沖的場(chǎng)景下使用,每一個(gè)大池子大小為 1MB。
值得注意的是,大型緩沖池的擴(kuò)容又分為 線性增長(zhǎng) 和 指數(shù)型增長(zhǎng),可以看出內(nèi)存可被高效的反復(fù)使用并且對(duì)調(diào)用者還是無(wú)感知的,這就是為什么 RecyclableMemoryStream 比 MemoryStream 更好更高效的原因。
當(dāng)調(diào)用 GetBuffer() 方法時(shí),小緩沖區(qū)將會(huì)轉(zhuǎn)換為一個(gè)大的連續(xù)緩沖區(qū),如下代碼所示:
var?buffer?=?recyclableMemoryStreamManager.GetStream().GetBuffer();安裝 RecyclableMemoryStream
你可以通過 Nuget 可視化界面安裝 Microsoft.IO.RecyclableMemoryStream 或者通過 NuGet package manager console window 執(zhí)行如下命令。
Install-Package?Microsoft.IO.RecyclableMemoryStream使用 RecyclableMemoryStream
安裝好之后,接下來(lái)我們通過 RecyclableMemoryStream 將數(shù)據(jù)寫入到 MemoryStream 中,值得注意的是,RecyclableMemoryStreamManager.GetStream() 方法返回的是 MemoryStream 實(shí)例。
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();}}上面的代碼還有一點(diǎn)要注意,我將 RecyclableMemoryStreamManager 靜態(tài)化了,意味著它只需要定義一次就ok了,還有一點(diǎn)你可以對(duì) MemoryStream 進(jìn)行標(biāo)記,方便后續(xù)持續(xù)跟蹤,如下代碼所示:
using?(var?memoryStream?=?recyclableMemoryStreamManager.GetStream("High_Performance_Stream_Demo.Program.Main")){memoryStream.Write(buffer,?0,?buffer.Length);}對(duì) MemoryStream Pool 精細(xì)化配置
如果你想對(duì) MemoryStream Pool 做更精細(xì)化的配置,可以在 RecyclableMemoryStreamManager 實(shí)例上進(jìn)行配置,如下代碼所示:
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 最佳實(shí)踐
內(nèi)存碎片會(huì)影響到程序的性能,而且LOH獨(dú)有的鏈?zhǔn)焦芾硪卜浅H菀桩a(chǎn)生內(nèi)存碎片,下面是使用 RecyclableMemoryStream 應(yīng)該遵循的一些經(jīng)驗(yàn)法則。
根據(jù)你的業(yè)務(wù)場(chǎng)景設(shè)置合適的 blockSize, largeBufferMultiple, maxBufferSize, MaximumFreeLargePoolBytes, MaximumFreeSmallPoolBytes 值。
當(dāng)使用完 Stream 對(duì)象時(shí)一定要速速關(guān)閉。
永遠(yuǎn)不要調(diào)用 ToArray() 方法。
盡可能避免調(diào)用 GetBuffer() 方法。
Microsoft.IO.RecyclableMemoryStream 是 MemoryStream 的池化對(duì)象,它技巧性的減少了 GC 的負(fù)載并減少了 LOH 的大對(duì)象分配,自然就提高了應(yīng)用程序的性能,不僅避免了內(nèi)存碎片和內(nèi)存泄漏還提供了用于跟蹤性能的指標(biāo)。
譯文鏈接:https://www.infoworld.com/article/3597060/how-to-use-recyclablememorystream-in-net-core.html
總結(jié)
以上是生活随笔為你收集整理的池化对象 RecyclableMemoryStream 在 .netcore 中的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core和json请求这
- 下一篇: IComparer与IEqualityC