Animal myAnimal = new Animal();
I have this code above. As far as I know, it will do these things :
The Java Virtual Machine Specification states
There are three kinds of reference types: class types, array types, and interface types. Their values are references to dynamically created class instances, arrays, or class instances or arrays that implement interfaces, respectively.
and clarifies
Values of type reference can be thought of as pointers to objects.
So the variable myAnimal
in
Animal myAnimal = new Animal();
is storing a pointer to the Animal
object on the heap.
You ask
How does the memory address value look like?
A memory address is typically just a numerical value that's an offset into the process' allocated memory. When a process reads that value, it can directly address that location and read from or write to it (think of it as an offset index in an array).
The object itself is more than just its address. In fact, its address can change multiple times over the lifetime of the JVM process as the garbage collector moves objects around.
However, the JVMS does not specify the internal structure of an object.
The Java Virtual Machine does not mandate any particular internal structure for objects.
In some of Oracle’s implementations of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data.
This doesn't help greatly, but we can assume that the memory allocated for the object data has to be large enough to contain all the object's fields and the data needs to be accessible quickly, ie. in constant time, as opposed to proportionally to the amount of data. The typical solution is to again use offsets. Take this class for example
class Animal {
private String name;
private byte height;
}
The field name
is of type String
, a reference type, which we know essentially just stores a pointer. If we assume our JVM only needs 32 bits to store a pointer, we know we only need 32 bits for this field.
The field height
is of type byte
, which is specified to only need 8 bits.
So each Person
object really only needs 32+8
bits, 5 bytes for its data. The JVM will most likely allocate more than that for its internal organization, but let's simplify to just those 5 bytes. In your example, the JVM will allocate the first 4 bytes for the name
and the next byte for the age
. Something like
0 8 16 24 32 40
+--------+--------+--------+--------+--------+
| name | height |
You ask
Is that one address or numerous address value? If only one, how can myAnimal have accesses to all object fields of Animal object like myAnimal.name, myAnimal.height,...?
myAnimal
holds only one address, but an expression like
myAnimal.height
can be thought of as reading 1 byte (because we know height
is of type byte) from memory at the address determined by adding 4 (because the location of the data for height
is offset by the 4 bytes needed for name
) to the value stored in myAnimal
.
Consider myAnimal
storing a pointer to a memory address of 12
, initialized with a name
pointing to a String at memory address 1345
and a height
value of 6. In memory, that could look like
myAnimal
|
v
Heap: ...12.......13.......14.......15.......16.......17
Object offsets: ....0 1 2 3 4 5
....+--------+--------+--------+--------+--------+
| 1345 | 6 |
To read myAnimal.height
, the JVM would calculate 12 + 4 = 16
and read the byte (6
) at that offset. To assign a new value to myAnimal.name
, the JVM would calculate 12 + 0
, and write 4 bytes representing some the new pointer value, overwriting the 1345
.
When an object is created, java does not share its Actual Memory Address
with refrence variables instead of that Java creates an index number
for your object
,which is passed to the reference variable
of that object. So, you are able to access your object with help of that index number
. Further your object hold the refrences
of its children
and help you to access them.
This is an oversimplification:
It's just a number that represents some address location; how big that number is depends on your computer's architecture (32 bit or 64 bit)
It is one address value; it is the address location of the place where your object representation in memory starts.
You can compare it with the address of your house. It has one address. All rooms in your house (fields) have a different location, but you have to enter through your front door (the 'start' location). Room locations are relative to your front door. I admit this example is a bit contrived, but you get the point...
Addresses are just long
numbers to denote the memory location of your object. And they depends on the bit's of the machine. It is 64 bit long on 64 bit machine and 32 bit long on 32 bit machine.
How does the memory address value look like?
If you are really enthusiastic to see those big numbers in your console, you can actually explore the Unsafe API
public native long getAddress(long address)
Fetches a native pointer from a given memory address. If the address is zero, or does not point into a block obtained from #allocateMemory , the results are undefined.
If the native pointer is less than 64 bits wide, it is extended as an unsigned number to a Java long. The pointer may be indexed by any given byte offset, simply by adding that offset (as a simple integer) to the long representing the pointer. The number of bytes actually read from the target address maybe determined by consulting #addressSize .
Is that one address or numerous address value? If only one, how can myAnimal have accesses to all object fields of Animal object like myAnimal.name, myAnimal.height,...?
Well it should be one on top level and that address location may contain address locations of others (I am not really sure)
I have not really tried running this on my machine.