[英]Are static class members pinned?
我有一個C#類,有一個靜態的ImageList對象。 此圖像列表將與我的應用程序中的多個表單上的各種ListView標頭(通過SendMessage ... HDM_SETIMAGELIST)共享。
雖然我理解靜態對象不符合垃圾收集的條件,但我不清楚它們是否也不符合垃圾收集器的重定位(壓縮)條件。 我是否還需要固定此對象,因為它與非托管代碼共享,例如,使用GCHandle.Alloc?
環境是VS 2008,Compact Framework 3.5。
實例本身不是靜態的。 參考是。 如果您使引用為空,則實例將符合GC的條件。 在內部,所有靜態實例都是通過固定數組的固定句柄引用。 即實例被運行時隱式固定。
如果您查看聲明為靜態成員的實例的GCroot,您將看到如下內容:
HandleTable:
008113ec (pinned handle)
-> 032434c8 System.Object[]
-> 022427b0 System.Collections.Generic.List`1[[System.String, mscorlib]]
如果使靜態引用為空,則固定數組中的相應條目也將為空。
現在,這些顯然是實現細節,因此它們可能會發生變化。
我是否還需要固定此對象,因為它與非托管代碼共享,例如,使用GCHandle.Alloc?
是。 如果沒有固定指針, GC
可以自由移動那個內存,所以你可能有懸空的C++
指針,指向一些無效的,或更糟的是,根本沒有內存。
此外,應澄清“共享”一詞。 如果你分配並傳遞給非托管內存,將其復制到某個地方,你可以避免不斷地固定它們。 取決於將控制權交給非托管環境后會發生什么。
編輯
即使考慮到@Brian的有趣答案,我仍然會選擇固定指針。 為了在代碼中明確指出固定指針的概念,避免在將來的代碼維護中出現任何可能的錯誤並保持清晰。
是。 你需要固定物體。
雖然引用是靜態的,也就是說,您可以從您的成員訪問此位置,它的引用仍然是GC句柄。 也就是說,它有資格進行垃圾收集(和/或壓縮),但它當然永遠不會發生。
我不認為認為靜態修飾符意味着它最終會在內存中有一個靜態位置是不一定錯的,但更大的問題是沒有API允許你在沒有固定對象的情況下獲取內存地址。 是否被GC移動。
而且,每個靜態成員對於每個AppDomain都是unqiue(不是進程)。 同一個靜態成員可以存在於同一進程的不同內存位置,並且可以在AppDomain卸載時進行垃圾回收。 這是我承認的邊緣情況,但即使可以在沒有釘扎的情況下完成,也沒有釘住對象的真正優勢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.