Sign in to follow this  
zoblin

C# sizeof

Recommended Posts

I want to declare an array (system.array) of nodes (my own Node class) that is a specific size. As in I want to declare a (for example) a 10 MB array and have the array be however many Node objects long to make that happen. (technically the largest whole number of Nodes that will be less than the given size, ie rounding down). Instinctively I want to do something like: Node[] memory = new Node[size / sizeof(Node)]; Of course this doesn't work, since sizeof only works on value types. Is there an alternate way of doing what I want to do? Basically I'm trying to allocate one big chunk of memory and do all my object manipulations within that rather than allocating and deallocating (or rather having the GC de-allocating when it feels like it) all over the place. In this case the class is composed of all value objects so I could create my own sizeof member function for my class easily enough by just adding the sizeof() each member variable, however, this is problematic for 2 reasons. One, I'm likely to make mistakes keeping the sizeof function consistant as I add and remove member variables during development. Two, it won't take into account padding. Thanks.

Share this post


Link to post
Share on other sites
Note: 10MB is a poor example, I'm talking about wanting to allocate (technically force the .NET memory manager to allocate) a very big chunk, possibly on the order of hundreds of MB or a GB or so. (the actual amount will be user configurable, of course).

Share this post


Link to post
Share on other sites
You can't do this in a painless and reliable fashion. I'm assuming you're trying to optimize to the garbage collectors behavior to improve performance, but this is not really the way to go about it.

First of all, there is no particular need to try to trick the collector by allocating an array of a particular size, except to ensure the object lives on the Large Object Heap -- for that you need only ensure that the object is at least 85,000 bytes, which is easy to determine since its a lower bound (EDIT: to clarify, though, this doesn't mean its easy to get your array objects on the LOH).

That said, you shouldn't assume that the LOH is necessarily faster; it just behaves different (for example, doesn't compact) which may or may not be a benefit. You also seem to be assuming that the GC behaves a certain way which is incorrect -- the GC does not deallocate "when it feels like it," it deallocates at some point after it can, which means the objects in question (at least on the desktop GC) are no longer reachable by your code. Keeping strong references to the objects (e.g., keeping them in an array that you always have around) is sufficient to prevent the GC from trying to collect them, regardless of the actual size of that array.

Keeping objects in pools like this is not quite as straightforward as it might seem from a performance benefit. You really need to understand how the GC operates on your platform -- in particular, how you reference things if its a generational collector like the desktop one, because you don't want to force bigger generation collections if you can avoid it.

Really, I can't see a whole lot of potential benefit from what you're trying to that you won't get from simply keeping the array around and not caring about its size.

There are a lot of good blogs on the subject of GC performance out there on MSDN.

Share this post


Link to post
Share on other sites
When using reference types, the garbage collector is free to move the objects around as it wishes. So, unless you configure the garbage for it (which I am not certain is possible), you can't create a fixed buffer of reference type objects (even if you knew their size, which you don't).

If you want fine control, use value types. Otherwise, let the garbage collector do its job.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
When using reference types, the garbage collector is free to move the objects around as it wishes. So, unless you configure the garbage for it (which I am not certain is possible), you can't create a fixed buffer of reference type objects (even if you knew their size, which you don't).

If you want fine control, use value types. Otherwise, let the garbage collector do its job.


While it's true that you generally shouldn't mess with this stuff and should let the garbage collector do its thing, it is possible to customize the behavior. You can fix variables so that they don't move around, allocate memory on the stack where it isn't affected by the GC, and other fun things. See fixed and stackalloc.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this