Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a binary file save on disk of size 15KB but why its memory size is always 4 bytes only

long mem1=GC.GetTotalMemory(false);
Object[] array= new Object[1000000];
array[1]=obj; // obj is the object content of the file before it is saved on disk
long mem2=GC.GetTotalMemory(false);
long sizeOfOneElementInArray=(mem2-mem1)/1000000;

I am wrong about something somewhere. I think it is incorrect because 4 bytes is not enough to store even a hello world string, but why is it incorrect. Thanks for any help.

Before the object is saved onto disk as a binary file, it is an object namely obj that I am trying to see how much memory it consumes . It's 4 bytes. Do you think I am correct about the way I retrieve its memory use ? – PointedC Nov 19, 2011 at 1:55 @PointedC, style rant - please do not name object for public code with meaningless names (like x, fooBar44,...) - it is hard to understand what intention of x is... try to never name anything "o", "l" as not everyone uses fonts where they are distinctly different from "0" and "1". – Alexei Levenkov Nov 19, 2011 at 3:01

Is the assumption that by assigning obj to the index [1] in the array o that it would take a substantial number of bytes? All you are doing is assigning a reference. Not only that, but all that new Object[1000000] did was create an array (space to associate 1,000,000 Object's and the memory required by Object[].), not allocate 1,000,000 Object's. I am sure someone can elaborate even more about the internal data structures being used and why 4 bytes shows up.

The key thing to realize is that assigned obj to o[1] is not allocating additional memory for obj. If you are trying to determine an approximation call GC.GetTotalMemory before obj is allocated, then after. In your test obj is already allocated before you call the first GC.GetTotalMemory

+1. Yes, the code in the question discovers that on particular platform (x86 is default for VS 2010) the size of object reference is 4 bytes. – Alexei Levenkov Nov 19, 2011 at 3:07

In general, when MSDN documentation says things like A number that is the best available approximation of the number of bytes currently allocated in managed memory it is a bad idea to rely on it for accurate values :-)

All kidding aside, if your object 'o' is not used in the function after line #3 in your example, it is possible that it is being collected between lines 3 and 4. Just a guess.

First, if I use the code as written, x becomes 0 for me, because o is not used after the assignment, so the GC can collect it. The following assumes o is not collected (e.g. by using GC.KeepAlive(o) at the end of the method).

Let's look carefully what each of the two important lines of your code do (assuming 32-bit architecture):

Object[] o = new Object[1000000];

This line allocates 1000000 * 4 + 16 bytes. Each element in the array takes 4 bytes, because it's a reference (pointer) to an object. 16 bytes is the overhead of an array.

o[1] = obj;

This line changes one of the references in o to reference to obj. This line allocates exactly 0 bytes.

I'm not sure why are you confused about the result. It has to be 4, unless there are some unreferenced objects from earlier part of the code. In that case, it could be less than 4 (even a negative number). Of course, if this were a multi-threaded application, the result could be pretty much anything, depending on what other threads do.

And this all assumes that GetTotalMemory() is precise, which it doesn't have to be.

In my experience, marshal.sizeof() is generally a better method of getting an object's true size than asking the garbage collector.

http://msdn.microsoft.com/en-us/library/y3ybkfb3.aspx

Marshal.SizeOf() is for getting the size of the masrshaled form of the object, it doesn't have to be the same as the normal size. (I'm not saying GetTotalMemory() is the correct way to do that, but Marshal.SizeOf() clearly isn't.) – svick Nov 19, 2011 at 3:40

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.