Re: High Memory Consumption of Classes and Arrays




"Christian Rattat" <groupanswers@xxxxxxxxxx> wrote in message
news:faef6c7b.0504302255.1766995a@xxxxxxxxxxxxxxxxxxxxx
> Hi,
>
> on my way to implement a data structure with csharp I have noticed
> that classes and arrays in dotnet consume very much memory.
>
> - An instance of an empty class without any properties consumes 24
> bytes

(note that all numbers from here assume you are using a 32bit processor, if
you are using a 64 bit proc and runtime then references and probably the
object header will have to increase).

I'm pretty sure it should be 8(which is the size of the class header, 12 if
you consider the reference as well). How are you determining the size of a
given object?

> Only a few bytes, hmmm? My DS is intended to handle hierarchical
> structures of up to a million objects. Each object has 2 collections
> plus a few fields (24 Bytes). Before I started implementation I
> thought about design and checked that (what I expected) each object
> would consume 24 bytes. When I started a performance test I noticed
> that instead of 24 MB memory 580 MB had been allocated.

Then you were mistaken. First off, why would you assume that two collections
are only the size of their reference? While the data contained in *your*
object will only be 4 bytes, the ArrayList class's fields take up...16
bytes. These bytes are taken up by

1) a reference to an array which contains the actual items.
2) an int32 field containing the current size of the ArrayList
3) a reference to an object to use for synchronization, as bad of an idea as
that was
4) an int32 version field used to properly implement the IEnumerator
pattern.
>
> Now, what is the reason for an empty array needs 16 bytes and an empty
> class needs 24 bytes? I mean it's nothing special to deal with a
> million objects. I did this many times with C++.
>
And assuming that the way C++ does things is the way everyone does this will
be your undoing. Learn the framework and its idiosynchrosies instead of
trying to use it like another language.

> Second thing: Why isn't in dotnet a sizeof operator that determines
> the byte size of an object of a managed reference type? I took me
> fu...ing long to find out at all where is all the memory gone. Who has
> designed this crappy thing? (before anybody wastes time for an answer:
> yes I have tried Marshal.SizeOf and any hints in the NGs and no, it
> didn't work.)

Because there is no way to accuratly determine the size of a managed type in
managed memory. The runtime is pretty much free to layout a class in any
order it wants(unless you tell it otherwise, and even then I don't think tis
required to for reference types) or even theoretically adjust the space
taken up by a variable if it can statically determine it safe, therefore the
size of an object can vary between one runtime and another or potentially
even on different runs(or maybe even the same instance, if a garbage collect
happens between the two sizeof calls).


>
> One could think that a class needs a few bytes for polymorphic stuff.
> But in this case a sealed class should need less memory. Wrong, sealed
> doesn't make a difference.

Why would you say a sealed class wouldn't need polymorphic stuff? Can a
sealed class not override ToString or other virtual methods it inherited?
Does being sealed mean the class cannot be refered to by a variable with a
base type? This statement makes no sense at all. If sealed classes don't
need a vtable pointer then what would the following do?(Mind you, string is
sealed)

object o = "MyString";
Console.WriteLine(o.ToString());

If you said print "MyString", you are wrong. The actual output without
support for a vtable would be "System.String"

>
> So finally, my tiny class that actuall needs to manage 24 bytes of
> data uses 184 bytes, or in other words 87 percent of data are
> overhead!
>
> Anybody here had the same problem and (I don't even dare to hope)
> found a solution?

Without knowing your architecture, I certainly can't offer much advice. Have
you tried using structures instead of classes?


.



Relevant Pages

  • Re: How to give selective access to the methods in a class?
    ... different memory locations at different times. ... The reference still leads to the ... So array resizing ... program pushes certain objects into the circular buffer, ...
    (comp.lang.java.programmer)
  • Re: High Memory Consumption of Classes and Arrays
    ... Only the array itself has overhead. ... memory as a reference type. ... > least consume 40 bytes of memory. ...
    (microsoft.public.dotnet.framework.performance)
  • Re: High Memory Consumption of Classes and Arrays
    ... >you consider the reference as well). ... each object created the free memory decreased by 52 ... know the dotnet platform but also c++, java, perl and other programming ... least consume 40 bytes of memory. ...
    (microsoft.public.dotnet.framework.performance)
  • Re: pinning types via Fixed
    ... > Now, for correctness, shouldn't he be locking the reference to the ... The array cannot be garbage collected since there is still a refererence on ... But it might be moved in memory when not beeing fixed so it is IMHO ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Garbage Collection Issues in long-standing services
    ... The problem with sockets is the unmanaged memory buffers used by the ... (probably a byte array) ... The result is that, depending of the number of buffers, ... > reference between CS and AP, so I don't explicitly set each reference to ...
    (microsoft.public.dotnet.languages.csharp)