Memory Address of Variables in Java

Memory address of variables in Java

That is the class name and System.identityHashCode() separated by the '@' character. What the identity hash code represents is implementation-specific. It often is the initial memory address of the object, but the object can be moved in memory by the VM over time. So (briefly) you can't rely on it being anything.

Getting the memory addresses of variables is meaningless within Java, since the JVM is at liberty to implement objects and move them as it seems fit (your objects may/will move around during garbage collection etc.)

Integer.toBinaryString() will give you an integer in binary form.

How to print address of a variable in Java

There is no element in the java language that allows you the get the address of anything and more importantly there is no language element ever requiring an address for anything. Thats why there is no address-of operator in java. The whole language is designed to work without.

The whole concept of memory address is abstracted in java; the closest you can get is a reference, but that is limited to actual objects. While the reference's value is actually a memory address (or at least something easily convertible into a memory address, see compressed OOPS), there is no way of converting that value to anything else. And again there is no need to ever do this, except maybe for satisfying your curiosity.

It is however possible, by using the (attention: not portable, not meant for actual public use!) java.sun.misc.Unsafe, this class allows converting the value of a reference to a long (representing a memory address). Example for using it can be found here: https://dzone.com/articles/understanding-sunmiscunsafe.

Are variables in Java and C/C++ the memory location or the value saved in that memory location?

C and Java passes everything by value, there is no other way. That is also the default for C++, but it has extra notation for passing arguments as references.

Passing something by value means that a new variable is created and it is internal to the method/function:

// C/C++, Java
void something(int x){
x=10;
// printf/cout/System.out.println x here, and it will be 10
}

void usesSomething(){
int y=5;
// printf/cout/System.out.println y here, and it will be 5
something(y);
// printf/cout/System.out.println y here, and it will be 5, x was just a copy
}

And Java objects are not different:

void something(String x){
x=new String("something");
System.out.println("In something: "+x);
}

void usesSomething(){
String y=new String("Hello!");
System.out.println(y); // "Hello!"
something(y);
System.out.println(y); // again "Hello!", x was just a copy
}

The confusing part is the wording only, as the variables themselves are called "object references" in Java (they would be "pointers" in C/C++). But they (the object references) are passed by value, nothing happens to y in this code.

Passing something by reference means that doing anything with the reference will directly affect the original variable.

// C++ only
void something(int &x){
x=10;
}

void usesSomething(){
int y=5;
std::cout << y << std::endl; // it is 5
something(y);
std::cout << y << std::endl; // it is 10, x was the same variable as y
}


One thing which may be worth mentioning is that an object and a variable are never the same thing in Java. Objects reside on the heap (like the deliberately exaggerated "Hello!" and "something"), while the reference variables to these objects (x and y) can reside anywhere (here they reside on the stack), and they have their own memory for storing the reference to these objects (in C/C++ it would be very much like a pointer, which also has a size, something like 4-8 bytes).

So in the general case this is how object can 'feel' being passed by reference: you actually pass the object reference by value, ending up referring the same object. If the object is mutable (Strings are not), changes will be visible from the outside, via any other variable referring the same object. But the reference variable itself is your own, if you change it (and refer to a different object, perhaps null), no one else will notice.

How can JVM map a variable name to its memory address?

When the program is running, there is no variable names except for debugging purposes. The details of how the program runs depends on the JVM design however for the OpenJDK / OracleJVM, compiles the byte code down to native code and in which case it is machine code which is really running the code. The variable "name" is assigned an offset in the object e.g. +16 from the start.

how can JVM lookup the addresses of the variable "height" and "name" to store values?

The memory at object+16 is read (or written) as an address or a Compressed Oops. e.g. say you have a 32-bit JVM to keep things simple, there is a 4 byte value at 16 bytes after the start of the object, this is the address of the Object used as the String.

Cat cat = new Cat();

This creates a new object by allocating enough memory on the heap. Say it is 24 bytes long. At first the data is full of zero (except the header which records the type as a pointer for example)

The constructor of the class is called to initialise the memory just allocated.

cat.height = 100;

Say height is assigned the offset + 12 from the start of the object. In this case the address of cat which is a number is added to 12, and the memory at this location is assigned the value 100 as a 4 byte store.

cat.name = "Tom"; 

Say name is assigned the offset +16 from the start of the object (and we are using 32-bit references) In this case the address of cat which is a number is added to 16, and the memory at this location is assigned the value of the reference which points to a String "Tom" as a 4 byte store.

There is always a table mapping variable names and addresses of all class fields, on the "method area" of JVM and it just searchs on there. Is this explanation correct?

Looking up a table each time is very expensive. Instead the offsets of each field is written into the machine code (once it is compiled) and the addition of the offset takes no extra time for most CPUs.

Generally, I don't even understand how a computer can recognize what memory address I am talking about just by looking at a variable name on my code.

The name is turned into a number which is the offset of the field from the start of the object.

is it possible to get address on heap of a variable in java?

i am working on a program that gets as
input java program , and instruments
code that prints out to file
information about variable access. The
only way that i can determine between
two fields of objects of the same
class is by thier address on heap.
Therefore, i need the address on heap

You can use System.identityHashCode to get a notion of sameness.
It's not perfect, but it's pretty good.
If you do get the heap address of an object, remember that the JVM is allowed to move objects around (and frequently does when a generational garbage collector promotes a long lived object to an older generation) so the heap location of an object is not a good proxy for identity in all circumstances.

How to find the memory address of a Java local variable programmatically using a native code?

the JNI provides a mechanism for accessing the java variables in the native code, this is described here: http://www.math.uni-hamburg.de/doc/java/tutorial/native1.1/implementing/field.html

then you can use

  &x; // gets the address of x

to get the address of your variable

another approach is to use assembler, i.e. the following code prints the begin of the stack (by printing the address of stack pointer and base pointer)

#include <stdio.h>

unsigned long get_sp(){
__asm__("mov %rsp, %rax ");
}

unsigned long get_bp(){
__asm__("mov %rbp, %rax ");
}

int main(int argc, char **argv)
{
int n;
printf("SP 0x%x\n", get_sp());
printf("BP 0x%x\n", get_bp());
return 0;
}


Related Topics



Leave a reply



Submit