简体   繁体   中英

Java primitive types and objects structure in memory

When we create a Java primitive variable or a Java object, how it is represented/structured in memory ?

int A;

// is a reference to an integer type created ?
// is the memory space necessary to hold an integer type allocated in memory ?

A = 3;

// is it now that the memory space necessary to hold an integer type is allocated ? then A reference that space.

int B = 2;
A = B;

// is A referencing the memory location as B ? and the old memory location that was referenced by A is Garbage Collected ?
// if yes, then modifying A will result in modifying also B, correct ?
// if no, then a pass by value has been done.
// has the memory location referenced by A been modified, or a new memory location capable of holding int has been created, filled with the value referenced by B then getting referenced by A ?

Is it the same analogy if A was a class object ?

Primitives in Java go onto the stack, so they are stored in the location of the variable. Keep in mind that though a String is considered immutable it is not a primitive, but a class.

So variable A and B both hold the value 2, but are not sharing the value. A side note is that Java does something funny with int variables. If they are low enough they are actually not even stored on the stack but reference a static allocation in memory (the pre compiler handles that).

Now for the part if you would assign an class instance. Then things change a bit. If you assign an instance to A you would assign a reference to A on the stack and allocate it on the heap. When you then assign A to B both would reference the same instance in the heap. This instance will not be garbage collected until both references go out of scope.

If you re-assign either A or B they will no longer point to the same instance in the heap.

The memory management, which goes on stack : not on heap, in your scenario can be depicted as below: 在此处输入图片说明

When you do, A=B , the memory allocated for integer referenced by A becomes eligible for GC.

Now, when you do a modification on either variable, you are referencing to other memory location corresponding to that value, and since it is on the stack, it won't affect the other.

For example, doing A = 6 , won't affect the value of B ; B still holds value as 2 .

And finally, it is not same as of in case if A was a class object since object goes to Heap Memory.

Take a look into this Wiki article, I find it pretty explanatory.

Each and every type of Data Type has a different amount of data that is allocated to store that data type, and this is why we have limits on how large, for example, an integer can be (-2,147,483,648 to 2,147,483,647, a maximum of 32 bits). Other data types, such as floats and doubles, have different values, where a float is a 32 bit floating point value, and a double is a 64 bit double precise floating point value.

As for your question on if you change B, will it change A, the short answer is no. What you're doing when you define a variable A equal to B, is you're changing the value of A to be equal to B. Another example, if you have the below code (any OO language), what your'e doing is creating a place in memory with a value of zero (and allocated space of 32 bits), and you are creating a second new variable with the value of the variable a , which is zero. edit: the second variable is entirely independent of the first.

int a = 0;
int b = a;

There is such a thing where one variable can be modified by changing the original value, and this is called a pointer. A pointer is a special little tool that holds the information about where in the memory the data is stored, otherwise called a memory address. Take a look at the code below.

Person* person = new Person();
int* age = person.age;

Here I'm declaring two pointers, one that is a reference to an object that is being instantiated, and one that is a link to a field in that object. The pointer stores the information of where the given data is stored in the memory (the memory address). From this, whenever using a pointer, it acts as a pointer to that memory address for us to access. Because of this, it isn't really a variable, but acts as a listing in a "table of contents" where you can use it to look up a piece of data. Because it doesn't directly store any data, but rather is just a reference to stored data, when changing directly the age of the person with person.age , it will also update it's data in memory, but the address stays the same, and will reflect on the pointer.

As for the question of garbage collection, in a language like Java or C#, data is only garbage collected when there is no longer any references to that piece of information. However, in a language such as C++, there is no garbage collection automatically, and you must delete pointers that you create with a delete keyword.

Anyways, hope this helps!

For Primitive Types :

int i = 10;
int j = i;
i = 11

In java 8 byte of memory is allocated for value of i and j (4 byte for i and 4 byte for j). The value of i is passed to j and now j and i have same value but different memory address. Now value of i is changed to 11 meaning for same memory address the value of i is changed from 10 to 11 but value of j is in different memory location and so it remains as 10.

在此处输入图片说明

In case of objects the value(or reference) itself is an address(or heap address) so if one changes it, it will be reflected for others as well. For example in objects :-

Person p1 = new Person();
Person p2 = p1;

在此处输入图片说明

So either p1 make changes or p2 make changes it will be changed for both. Whether it is Java, Python or Javascript it is same. In case of primitive it is the actual value but in case of objects it is a address of actual object - that's the trick.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM