嘗試使用本機「緩衝區」手動管理內存分配對於.NET來說最多是困難的。您不能將託管類型分配到非託管緩衝區,因此它們只能用於結構化數據,在這種情況下,與簡單的託管數組(它將連續存儲在內存中)幾乎沒有什麼優勢。
通常,嘗試管理對象分配和放開的方式通常是一種更好的方法,並嘗試根據需要手動重用它們(如果且僅當內存壓力對您而言是個問題時) 。
至於一些特定點:
我知道,對象分配是基於.NET更快然後在非託管堆和對象的破壞是因爲GC開銷.NET貴得多,所以我認爲使用非託管服務會快一點。
我認爲你在這裏的假設有點有缺陷。在分配點分配對象時,.NET中的對象分配通常更快,因爲CLR可能具有可以使用的預分配內存。對象「銷燬」在.NET上也更快,不過由於GC的原因,可能會更高一些(儘管並非總是如此),但延遲成本仍然存在。這裏有很多因素,主要集中在對象生命週期 - 如果您允許將對象升級到Gen1或特別是Gen2,那麼由於GC壓縮成本可能更高,事情可能難以跟蹤和測量。
什麼時候應該使用固定{}和何時Marshal.AllocHGlobal()?
一般來說,你會(很)很少在C#中使用。通常情況下,您最好不要固定內存,並允許GC正確執行其工作,這反過來會導致整體上更好的GC啓發式。
2)以我的理解是更有效的使用一週參考在.NET託管和非託管的緩衝區,如果緩衝可能一段時間後(根據和用戶操作)可重複使用,是不是?
不一定。重複使用對象並使它們長時間不活動也存在一些嚴重的缺陷。這可能會保證內存將被升級到Gen2,這可能會使生活變得更糟,而不是更好。
通常情況下,我的建議是相信系統,但是隨時測量。當且僅當您發現真正的問題時,幾乎總是有辦法解決那些特定問題(不訴諸非託管或手動管理內存緩衝區)。處理原始內存應該是處理託管代碼庫時的絕對最後手段。
當我需要將緩衝區傳遞給本地API時,最好是將託管的固定對象或堆上的非託管緩衝區傳遞給它? (例如我需要用零填充文件的緩衝區) –
@BransDs對於您的示例,我只是使用託管API來填充文件。一般來說,固定和傳遞固定指針可以避免不必要的複製。 –