88

What is the size of an object reference in .NET? Does it vary between x86, x64, and/or AnyCPU compilation?

If it makes a difference, I'm interested in C#.

David Klempfner
  • 8,700
  • 20
  • 73
  • 153
Matt Mills
  • 8,692
  • 6
  • 40
  • 64
  • [see related question][1] [1]: http://stackoverflow.com/questions/26570/sizeof-equivalent-for-reference-types – Tim Hoolihan Jan 23 '11 at 15:17
  • possible duplicate of [c# reference variable mem allocation](http://stackoverflow.com/questions/489805/c-sharp-reference-variable-mem-allocation) – nawfal Jun 07 '14 at 18:45

3 Answers3

99

The reference itself is basically a pointer. 32 bits on a 32 bit OS, 64 bits on a 64 bit OS.

The size of the object that's referenced is more complicated.

Samuel Neff
  • 73,278
  • 17
  • 138
  • 182
  • That's what I figured - I just wanted to make sure there wasn't more going on inside the runtime – Matt Mills Sep 27 '10 at 03:44
  • 1
    I wonder why 64-bit .net would have used a pointer, rather than an scaled offset into an "objects" table? A 32-bit scaled offset should have been sufficient for most applications (applications which need more than four BILLION objects could use a special "superHumungous" memory model), and I would think that the small extra cost of using scaled displacement addressing would be more than made up for by the improved cache concurrency that would result from making object references half as big. – supercat Dec 10 '11 at 19:46
  • 5
    @supercat, .NET developers can choose to compiler their app to 32-bit mode and all pointers will be 32-bit. This is probably best for any application that doesn't need 64-bit pointers, which is the vast majority of applications. – Samuel Neff Dec 11 '11 at 02:55
  • 1
    @SamuelNeff: According to other things I've read, 64-bit applications offer better performance because the 64 bit instruction set allows the use of more registers and is generally more efficient. I would think that using 32-bit object references would improve performance even further. – supercat Dec 11 '11 at 04:20
  • 2
    @supercat, there are many conflicting posts about 32-bit vs 64-bit performance. Here's one that strongly favors 32-bit. http://blogs.msdn.com/b/ricom/archive/2009/06/10/visual-studio-why-is-there-no-64-bit-version.aspx – Samuel Neff Dec 11 '11 at 05:22
  • @supercat, besides, the discussion on performance has nothing to do with the original question. – Samuel Neff Dec 11 '11 at 05:23
  • 2
    @SamuelNeff: While the original question could be answered "4 bytes on x86; 8 bytes on x64", that question in and of itself wouldn't be very interesting or insightful. Knowing what the performance implications are of 8-byte object references seem somewhat more insightful. – supercat Dec 11 '11 at 16:36
  • @ChrisBordeman read the original question more carefully. Everything you're talking about is within the object instance, not the reference to that object. It may not be the most interesting question to all, but it is a specific question. – Samuel Neff Apr 25 '17 at 05:27
  • 1
    @ChrisBordeman also I suggest you read ECMA-335 specification 12.1.1.3 which talks about object reference portability. And object reference must be portable to and from a native pointer. An object reference is the same size as a native pointer. All the other things you mentioned are in type references, type definitions, and the object being referred to. – Samuel Neff Apr 25 '17 at 19:59
  • @Samuel Neff I understand where you're coming from, but the question is really about the overall size of the reference, which really should include the data at the end of it. That's not strictly the "reference," but it sort of is. – Chris Bordeman Jul 07 '17 at 19:15
  • 2
    @ChrisBordeman what makes you think that? The OP says `object reference` and not `object`. The OP marked this answer as correct. – Samuel Neff Jul 09 '17 at 23:33
  • Because that stuff isn't part of the object, it's just nearby. It's a CLR implementation detail, really. You can have an "object" reference and its minimum size is 12 or 24 (32/64-bit). That "object" has no members yet it has a minimum size put there by this implementation of the CLR. That's conceptually not really the object but the reference. – Chris Bordeman Jul 11 '17 at 00:11
  • @ChrisBordeman do you have any links or references to support anything you're claiming? – Samuel Neff Jul 12 '17 at 05:03
  • @SamuelNeff Not off the top of my head, but if you'd like to read up a bit on the subject of reference structures in the Windows CLR implementation, that'd do the trick. – Chris Bordeman Jul 13 '17 at 05:58
  • @ChrisBordeman everything I've read, including the CLR spec, supports my answer and what I've been saying. That's why I asked for a specific link. – Samuel Neff Jul 14 '17 at 03:25
  • @ChrisBordeman What do you mean "this has all been said to you by others"? You're the only one claiming this answer is not correct and even though you seem to be paraphrasing the CLR spec you're not pointing to exactly where it supports what you're saying. – Samuel Neff Jul 16 '17 at 03:36
  • So just to be clear does this mean that if I declare new object[1024] that array will take up 32k (or 64k depending on cpu)? – Emperor Eto Oct 02 '19 at 20:41
  • 1
    @PeterMoore, this question is talking about the reference only, not the contents of the object that's referred to. Each reference is 32 bits or 64 bits, 4 bytes or 8 bytes, so if you have 1024 references that would be 4,096 bytes or 8,192 bytes. The reference to the array itself would be another 4 or 8 bytes. There may be additional metadata too, that I'm not sure about. This is also assuming that it is an array of objects. An array of primitives would be different depending on the type. – Samuel Neff Oct 08 '19 at 05:03
  • Oh yes I meant 4096 or 8192. Haha, I was confusing bits with bytes. Long day. – Emperor Eto Oct 09 '19 at 12:44
22

For determining pointer size, you can use System.Runtime.InteropServices.Marshal.SizeOf(typeof(IntPtr)), or sizeof(IntPtr) in unsafe context.

Edit:

Or IntPtr.Size.

IS4
  • 11,945
  • 2
  • 47
  • 86
16

An object reference is basically a pointer to the memory that contains the object's attributes. As such the reference is one processor word in length - 32 bits on 32 bit platforms and 64 bits on x64.

Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128