56

As a programmer I think of these as looking like "the java.lang.Object at address 1a234552" or similar for something like the s in

Object s = "hello";

Is this correct? Therefore are all references a fixed size?

5 Answers5

66

While on many VMs the size of a reference is the native pointer size (i.e. 32 bits for a 32 bit JVM and 64 bits for a 64 bit JVM) this isn't guaranteed - and in particular HotSpot either does now or soon will support "Compressed Oops" which are 32 bit references in a 64 bit JVM. (That doesn't mean that every reference is compressed - read the linked article for more information, and there are plenty of blog posts about it too.)

In response to another comment, note that the reference itself is typically just a way of addressing the object itself. Whether it's a direct memory pointer or not, its goal is to get to the data for the object. That's basically all that really matters. If there's some "spare" bits (e.g. it's a 64-bit reference and you don't need all of that width just to represent the object's location) then the VM can use that data for other information such as its type, which may allow some optimisations. (See Tom's comment for more details.)

The object itself contains type information (probably in the form of a reference to the instance of Class, or something similar - I don't know in enough detail) as well as other necessary "stuff" in the header, before you get to the user data for the object.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Azul do put some type information into the oop. IIRC, 48 bits are used for address and 16 for type information (I might be slightly out there, particularly if some of the bits at the bottom of the 48 are always zero). I believe this allows quick checking for inlined, non-megamorphic virtual method calls. – Tom Hawtin - tackline Jun 11 '09 at 14:06
  • What other memory is stored? For example: object type, casting info, polymorphic info, etc. Don't know if this are stored in the Object "header", but do you have idea of what else is stored from an object aside its references? – santiagobasulto Dec 17 '10 at 20:11
  • 2
    @santiagobasulto: It will vary by VM. Not a lot though - a reference to the class information, something to indicate its monitor (locking status etc), and possibly something used by the garbage collector. – Jon Skeet Dec 17 '10 at 20:14
  • @JonSkeet Why usually the size of a reference is equal to the word size? How does it help? – Geek Aug 04 '14 at 16:52
  • @Geek: Well I said it's normally the native *pointer* size - and as references are a special kind of pointer (or at least, can be implemented that way), it makes it very simple. The value of a reference can just be a pointer. – Jon Skeet Aug 04 '14 at 17:01
  • @JonSkeet May be I couldn't articulate my previous question. I meant to ask why the native pointer size is 32 bits for 32 bit JVM? Is it by definition? – Geek Aug 04 '14 at 17:13
  • @Geek: It's more that it's 32-bit for a 32-bit operating system, running on a 32-bit processor. That's pretty much the definition of what it means to be a 32-bit processor... – Jon Skeet Aug 04 '14 at 17:15
  • It is interesting that reference reads and writes [are atomic](http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html) even though they may be 8 bytes, unlike their long and double 8 byte counterparts (other primitives are atomic). – Ciro Santilli OurBigBook.com Mar 17 '15 at 14:12
  • 1
    @CiroSantilli: I suspect the idea is that references will only be 8 bytes wide if the underlying CPU and OS are 64-bit, in which case you're likely to get 64-bit atomicity for free... whereas on a 32-bit CPU you'd use 32-bit references, but long and double will still be 64-bit. – Jon Skeet Mar 17 '15 at 14:17
10

It is not a part of JLS or JVM Spec, but in practice it will be an address: 32 bit on 32 bit CPU, 64 at 64.

pqism: Okay got you, because after compilation we no longer care about the declared type?

We do care. That is why Class objects are there. In fact, from the other answers you can see that we care about types in runtime enough to optimize the way we work with them by putting part of type information into reference.

Georgy Bolyuba
  • 8,355
  • 7
  • 29
  • 38
  • 1
    32 bits doesn't seem very much if it includes the type information? –  Jun 11 '09 at 13:32
  • 2
    @pqism - The reference itself is probably just a pointer to the actual object. The type information would be stored with the rest of the object data. Maybe a better question would be "what is the minimum size for a java object, and what does it contain?" – Eric Petroelje Jun 11 '09 at 13:38
  • Okay got you, because after compilation we no longer care about the declared type? So it really is just "something at that address". –  Jun 11 '09 at 13:52
  • @pquism: Look at it this way. You may allocate an array `Object[10000]`, like the backing array of a Map. You actually don't know if all those entries will ever be used, and because of the load factor, they almost certainly won't. In that case, it would be extremely stupid to store type informations in the array sequence. It'll be better to have the type information on the individual objects themselves. – Sune Rasmussen Mar 12 '13 at 08:30
3

The size of an object reference depends on the JVM and machine architecture. Generally, on a 32-bit machine it is 32 bits and on a 64-bit machine it is 64 bits. However, I think that the OpenJDK 7 JVM will have support for "compressed pointers" that will save some room on 64-bit machines.

The information about the object's type is stored in the object itself; that is, if you follow the 32-bit or 64-bit pointer (or, more likely, handle) to the object, you would find another pointer to a Class instance that describes the type, as well as the data fields of the object.

asgs
  • 3,928
  • 6
  • 39
  • 54
erickson
  • 265,237
  • 58
  • 395
  • 493
2

I just want to add my 0.02$ that on 64-bit platforms, the reference can have 32 bits or 64 bits.

It can be of a 32 bit size when Compressed OOP is enabled (on by default).

The other way it can be of 32 bits is when the heap is smaller then 4 GB and it fits in the initial virtual space of 4 GB. For example:

0                            4GB
..................................................
|   < your heap fits here>    |

In such a case, the source code says that this is UnscaledNarrowOop type of heap alignment and for that type, the the references have 32 bits.

Eugene
  • 117,005
  • 15
  • 201
  • 306
2

Most people tend to see a reference to an object as a C-language-like-memory-pointer. While this is not technically correct, most implementations do implement it as a pointer. In case of compressed object pointers for example, the JVM stores only bits 3 to 34 of the 64-bit pointer on a 64 bit platform. Other implementations could also choose to use a different scheme: the reference could be an index into an pointer array containing all objects.

Rutger Nijlunsing
  • 4,861
  • 1
  • 21
  • 24
  • Do you mean to say that the JLS does not **forbid** other ways of storing object references (besides the C-language-like-memory-pointer way) ? – Pacerier Jan 28 '12 at 23:03
  • @Pacerier it's not the `JLS`, but `JVMS`, but otherwise - yes, the specification does not forbid that. – Eugene Jun 30 '20 at 18:36