Are the static members of the class bound?

I have a C # class having a static ImageList object. This list of images will be shared by various ListView headers (via SendMessage ... HDM_SETIMAGELIST) in several forms in my application.

Although I understand that static objects do not have the right to collect garbage, it is not clear to me whether they are also unsuitable for moving (compacting) the garbage collector. Do I need to bind this object as well, since it is used in conjunction with unmanaged code, say with GCHandle.Alloc?

Environment - VS 2008, Compact Framework 3.5.

+5
source share
3 answers

The instance itself is not static. There is a link. If you miss the link, the instance will be entitled to GC. Inside, all static instances are links through a pinned descriptor to a static array. That is, the instance is implicitly committed by the runtime.

If you look at the GCroot instance declared as a static member, you will see something like this:

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

If you remove the static link, the corresponding entry in the pinned array will also be null.

Now these are obviously implementation details, so they could potentially change.

+2
source

Do I also need to bind this object, since it is used in conjunction with unmanaged code, say, using GCHandle.Alloc?

Yes. If the pointer is not pinned, GC free to move this memory, so you may have C++ pointers pointing to some invalid or, even worse, not to their memory.

In addition, the “common” word should be clarified. If you select and go into unmanaged memory that copies it somewhere, you may not have to link them all the time. Depends on what happens when you transfer control to an unmanaged environment.

EDIT

Even considering the interesting answer from @Brian, I would still prefer to bind a pointer. To make the concept of a fixed pointer explicit in code, avoid any possible errors in future code maintenance and be clear.

0
source

Yes. You need to bind an object.

Although it’s true that the link is static, that is, you can access this location anywhere in your member, this link is still a GC handle. That is, he has the right to garbage collection (and / or compaction), but this, of course, will never happen.

I don’t think it’s wrong to think that the static modifier implies that in the end it will have a static location in memory, but there the big problem is that there is no API that allows you to get the memory address without binding the object. he moved GC or not.

In addition, each static member is unqiue for the AppDomain (not the process). The same static member can exist in different memory locations in the same process, and it can be garbage collection when the AppDomain is unloaded. This is a rather brief case, which I admit, but there is no real advantage to not pinning objects, even if it could be done without pinning.

0
source

Source: https://habr.com/ru/post/1235146/


All Articles