2015-11-03 16 views
5

Tôi có một lớp C#, có một đối tượng ImageList tĩnh. Danh sách hình ảnh này sẽ được chia sẻ với các tiêu đề ListView khác nhau (thông qua SendMessage ... HDM_SETIMAGELIST) trên một số biểu mẫu trong ứng dụng của tôi.Các thành viên lớp tĩnh có được ghim không?

Mặc dù tôi hiểu rằng các đối tượng tĩnh không đủ điều kiện thu gom rác, nhưng không rõ ràng đối với tôi nếu chúng cũng không đủ điều kiện để thu gom rác. Tôi cũng cần phải ghim đối tượng này vì nó được chia sẻ với mã không được quản lý, giả sử, sử dụng GCHandle.Alloc?

Môi trường là VS 2008, Compact Framework 3.5.

+0

Tôi không biết bản thân mình, nhưng tôi sẽ không phụ thuộc vào việc họ bị ghim ngay cả khi họ không có khả năng di chuyển. Nó có vẻ khá có thể là họ có thể được di chuyển vì nén chặt như các đối tượng khác được giải phóng xung quanh họ. – siride

Trả lời

0

Tôi cũng cần ghim đối tượng này vì nó được chia sẻ với mã không được quản lý , sử dụng GCHandle.Alloc?

Có. Nếu con trỏ không được ghim, GC là miễn phí để di chuyển bộ nhớ đó, vì vậy bạn có thể treo lơ lửng C++ con trỏ, trỏ đến một số con trỏ không hợp lệ hoặc tệ hơn, không phải bộ nhớ của chúng.

Ngoài ra, từ "được chia sẻ" phải được làm rõ. Nếu bạn phân bổ và chuyển đến bộ nhớ không được quản lý, bản sao đó ở đâu đó, bạn có thể tránh ghim chúng liên tục. Phụ thuộc vào những gì xảy ra khi bạn vượt qua quyền kiểm soát đối với môi trường không được quản lý.

EDIT

Thậm chí xem xét câu trả lời thú vị từ @ Brian, tôi vẫn sẽ chọn ghim con trỏ. Để làm cho rõ ràng trong mã khái niệm của con trỏ cố định, tránh bất kỳ misguide có thể trong việc bảo trì mã trong tương lai và giữ sự rõ ràng.

0

Có. Bạn cần ghim đối tượng.

Mặc dù sự thật là tham chiếu tĩnh, tức là bạn có thể truy cập vị trí này ở bất kỳ đâu từ thành viên của bạn nhưng tham chiếu của nó vẫn là một điều khiển GC. Nghĩa là, nó đủ điều kiện để thu gom rác (và/hoặc nén) nhưng tất nhiên nó sẽ không bao giờ xảy ra.

Tôi không nghĩ rằng nó là sai lầm khi nghĩ rằng bộ sửa đổi tĩnh ngụ ý rằng nó sẽ có vị trí tĩnh trong bộ nhớ nhưng vấn đề lớn hơn là không có API cho phép bạn nhận được địa chỉ bộ nhớ mà không cần ghim vật. Cho dù nó đang được di chuyển bởi GC hay không.

Hơn nữa, mỗi thành viên tĩnh là unqiue cho mỗi AppDomain (không xử lý). Thành viên tĩnh tương tự có thể tồn tại ở các vị trí bộ nhớ khác nhau trong cùng một quá trình và nó có thể là rác được thu thập khi tải xuống AppDomain. Đây là trường hợp khá cạnh tôi sẽ thừa nhận nhưng không có lợi thế thực sự của việc không ghim các đối tượng ngay cả khi nó có thể được thực hiện mà không cần ghim.

+0

Đối tượng ImageList của tôi cho thấy thuộc tính Handle, đó là những gì tôi chuyển đến mã không được quản lý, không phải là một giá trị được trả về bởi AddrOfPinnedObject(). Tôi có nên ghim chỉ thuộc tính Handle (đó là cấu trúc IntPtr) hay toàn bộ đối tượng ImageList không? – dablumen

+0

Bạn phải ghim đối tượng để truy cập đối tượng bằng phương thức 'AddrOfPinnedObject()'. Tuy nhiên, điều đó sẽ dẫn đến một con trỏ thô đến một đối tượng được quản lý nếu nó không phải là một mảng có ** blittable **. Tôi nghĩ rằng bạn thực sự nhận được ngoại lệ nếu bạn làm điều này với các loại không blittable, như bạn nên. Việc truyền trực tiếp Xử lý là yêu cầu chuyển 'gc_root' mà chỉ là một trình bao bọc xung quanh' GCHandle' và nó sẽ hành động phù hợp và ghim đối tượng khi cần để truy cập từ mã không được quản lý. –

2

Bản thân trường hợp không tĩnh. Tham chiếu là. Nếu bạn null tham chiếu thì cá thể đó sẽ đủ điều kiện cho GC. Trong nội bộ, tất cả các cá thể tĩnh là các tham chiếu thông qua một chốt được ghim vào một mảng các số liệu thống kê. I E. ví dụ này được gắn hoàn toàn bởi thời gian chạy.

Nếu bạn nhìn vào GCroot của một thể hiện khai báo là một thành viên tĩnh, bạn sẽ thấy một cái gì đó như thế này:

HandleTable: 
    008113ec (pinned handle) 
    -> 032434c8 System.Object[] 
    -> 022427b0 System.Collections.Generic.List`1[[System.String, mscorlib]] 

Nếu bạn null các tài liệu tham khảo tĩnh mục tương ứng trong mảng gắn được nulled như tốt.

Bây giờ, đây rõ ràng là chi tiết triển khai để chúng có khả năng thay đổi.

+0

thật thú vị. Bạn có một số bên trong khi triển khai? (bài viết, blog ..) Nguyên nhân có vẻ như không có nhiều thông tin về chủ đề bạn đang đề cập đến. – Tigran

+0

Đây là những chi tiết thực hiện tôi cho rằng, nhưng bạn có thể khai thác điều này bằng cách sử dụng WinDbg/SOS và thấy rằng tĩnh được xử lý như thế này. –

+0

Quan điểm của tôi là chi tiết triển khai hiện tại? Hoặc điều này là có gần như ngay từ đầu? Nói cách khác có thể là điều này, thậm chí có khả năng, có thể thay đổi? (Ngay cả với chi phí của khả năng phá vỡ mã di sản, nếu ai đó chuyển tiếp trên ghim ngầm trong mã hỗn hợp của mình) – Tigran

Các vấn đề liên quan