The heap and stack Java in Java divides memory into two types: one is stack memory and the other is heap memory.
Some basic types of variables defined in functions and reference variables of objects are allocated in the function's stack memory. When a variable is defined in a block of code, java allocates memory space for the variable in the stack. When the scope of the variable exceeds the scope of the variable, java will automatically release the memory space allocated for the variable, and the memory space can be used separately immediately.
Heap memory is used to store objects and arrays created by new. The memory allocated in the heap is managed by the Java virtual machine automatic garbage collector. After an array or object is generated in the heap, a special variable can be defined in the stack. The value of this variable is equal to the first address of the array or object in the heap memory. This special variable in the stack becomes a reference variable for the array or object. In the future, you can use the reference variable in the stack memory in the program to access the array or object in the heap. The reference variable is equivalent to an alias or code name for the array or object.
Reference variables are ordinary variables. When defined, memory is allocated on the stack. Reference variables are released outside the scope when the program runs. The array & object itself is allocated in the heap. Even if the program runs outside the code block where the statements that use new to generate the array and object are located, the heap memory occupied by the array and object itself will not be released. The array and object only become garbage when there is no reference variable pointing to it, and can no longer be used, but still occupy memory and are released by the garbage collector at an uncertain time. This is also the main reason why Java takes up more memory. In fact, variables in the stack point to variables in heap memory, which is the pointer in Java!
Heap and stack in Java
Java divides memory into two types: one is stack memory and the other is heap memory.
1. Stack and heap are both places used by Java to store data in Ram. Unlike C++, Java automatically manages stacks and heaps, and programmers cannot set up stacks or heaps directly.
2. The advantage of the stack is that the access speed is faster than the heap, second only to the registers located directly in the CPU. But the disadvantage is that the data size and lifetime in the stack must be deterministic and lack flexibility. In addition, stack data can be shared. The advantage of the heap is that it can dynamically allocate memory size, and the lifetime does not have to be told to the compiler in advance. Java's garbage collector will automatically collect the data that is no longer used. But the disadvantage is that the memory must be dynamically allocated at runtime, the access speed is slower.
3. There are two types of data in Java.
One is the basic types (primitive types), there are 8 types, namely int, short, long, byte, float, double, boolean, char(note,
There is no basic type of string). This type of definition is defined by a form such as int a = 3; long b = 255L; and is called an automatic variable. It is worth noting that the automatic variable contains literal values, not instances of the class, that is, not references to the class, and there is no class here. For example, int a = 3; here a is a reference pointing to the int type,
Point to the literal value of 3. Due to the size of these literal values, the lifetime of these literal values can be known (these literal values are fixedly defined in a program block, and after the program block exits, the field value disappears).
For the sake of pursuing speed, it exists in the stack.
In addition, a very important special feature of the stack is that the data in the stack can be shared. Suppose we define at the same time:
int a = 3;
int b = 3;
The compiler first processes int a = 3; first it will create a reference to the variable a in the stack, and then find out if there is an address with a literal value of 3. If it is not found, it will open an address with the literal value of 3, and then point a to the address of 3. Then process int b = 3; after creating the reference variable of b, since there is already a literal value of 3 in the stack, b is directly pointed to the address of 3. In this way, a and b both point to 3 at the same time.
It is particularly important to note that this literal reference is different from that of class objects. Assuming that the references of two class objects point to an object at the same time, if one object reference variable changes the internal state of the object, the other object reference variable immediately reflects this change. Instead, modifying its value through a literal reference will not cause another value to be changed accordingly. As in the above example, after we define the values of a and b, let a=4; then, b will not be equal to 4, or equal to 3. Inside the compiler, when a=4 is encountered, it will re-search whether there is a literal value of 4 in the stack. If not, re-open the address to store the value of 4; if it already exists, directly point a to this address. Therefore, the change in value a will not affect the value b.
Another type is packaging class data, such as Integer, String, Double, etc. that wraps the corresponding basic data types. All of these class data exists in the heap. Java uses the new() statement to display the compiler and only creates dynamically as needed at runtime, so it is more flexible, but the disadvantage is that it takes up more time.
In JAVA, there are six different places where data can be stored:
1. Register. This is the fastest storage area because it is located in a different place than other storage areas - the processor. However, the number of registers is extremely limited, so registers are allocated by the compiler according to requirements. You cannot directly control it, nor can you feel any signs of the existence of the register in the program.
2. Stack. Located in general purpose RAM, but with its "stack pointer" you can get support from the processor. If the stack pointer moves down, new memory is allocated; if it moves up, those memory is freed. This is a fast and efficient way to allocate storage, second only to registers. When creating a program, the JAVA compiler must know the exact size and life cycle of all data stored in the stack, because it must generate the corresponding code in order to move the stack pointer up and down. This constraint limits the flexibility of the program, so although some JA VA data is stored on the stack - especially object references, JAVA objects are not stored in it.
3. Heap. A universal memory pool (also exists in RAM) for storing so-called JAVA objects. The advantage of the heap is that the compiler does not need to know how many storage areas to allocate from the heap, nor does it need to know how long the stored data will last in the heap. Therefore, there is great flexibility in allocating storage in the heap. When you need to create an object, you only need to write a simple line of code in new. When executing this line of code, it will automatically store and allocate in the heap. Of course, corresponding code must be paid for this flexibility. It takes more time to allocate the storage with the heap than to store it with the stack.
4. Static storage. "static" here means "in a fixed position". Static storage stores data that has always existed when the program is running. You can use the keyword static to identify that a specific element of an object is static, but the JAVA object itself is never stored in static storage space.
5. Constant storage. Constant values are usually stored directly inside the program code, and it is safe to do so because they will never be changed. Sometimes, in an embedded system, the constant itself is separated from other parts, so in this case, it is optional to put it in the ROM.
6. Non-RAM storage. If the data survives completely outside the program, it can be left without any control of the program and can exist when the program is not running.
In terms of speed, there is a relationship as follows:
Register< Stack< Heap< Other
"The above passage is extracted from "Thinking in Java""
Question 1:
String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); //true
Question 2:
String str1 =new String ("abc"); String str2 =new String ("abc"); System.out.println(str1==str2); // false Question 3:
String s1 = "ja"; String s2 = "va"; String s3 = "java"; String s4 = s1 + s2; System.out.println(s3 == s4);//false System.out.println(s3.equals(s4));//true
Some basic types of variables defined in the function and reference variables of the object are all allocated in the function's stack memory.
When a variable is defined in a block of code, Java allocates memory space for this variable in the stack. When the scope of the variable exceeds the variable, Java will automatically release the memory space allocated for the variable, and the memory space can be used separately immediately.
Heap memory is used to store objects and arrays created by new.
The memory allocated in the heap is managed by the Java virtual machine's automatic garbage collector.
After an array or object is generated in the heap, a special variable can be defined in the stack, so that the value of this variable in the stack is equal to the first address of the array or object in the heap memory, and the variable in the stack becomes a reference variable for the array or object.
A reference variable is equivalent to a name given to an array or object. You can use the reference variables in the stack in the program to access the array or object in the heap.
Specifically: the stack and the heap are both places used by Java to store data in Ram. Unlike C++, Java automatically manages stacks and heaps, and programmers cannot set up stacks or heaps directly.
The Java heap is a runtime data area, from which objects allocate space. These objects are established through instructions such as new, newarray, anewarray and multianewarray. They do not require program code to be explicitly released. The heap is responsible for garbage collection. The advantage of the heap is that it can dynamically allocate the memory size, and the lifetime does not have to be told to the compiler in advance, because it dynamically allocates memory at runtime. Java's garbage collector will automatically collect the data that is no longer used. But the disadvantage is that because it needs to dynamically allocate memory at runtime, the access speed is slower.
The advantage of the stack is that the access speed is faster than the heap, second only to the registers, and the stack data can be shared. But the disadvantage is that the data size and lifetime in the stack must be deterministic and lack flexibility. The stack mainly stores some basic types of variables (,int, short, long, byte, float, double, boolean, char) and object handles.
A very important special feature of the stack is that the data existing in the stack can be shared. Suppose we define at the same time:
int a = 3;
int b = 3;
The compiler first processes int a = 3; first it will create a reference in the stack with a variable a, and then find out whether there is a value of 3 in the stack. If it is not found, it will store 3 and then point a to 3. Then process int b = 3; after creating the reference variable of b, because there is already a value of 3 in the stack, b is directly pointed to 3. In this way, a and b both point to 3 at the same time. At this time, if a=4 is set again; then the compiler will search again for whether there is a 4 value in the stack. If not, store 4 and point a to 4; if it already exists, point a to this address directly. Therefore, the change in value a will not affect the value b. It should be noted that this sharing of data is different from the sharing of references from two objects pointing to one object at the same time, because in this case the modification of a will not affect b, it is done by the compiler, which is conducive to saving space. An object reference variable modifies the internal state of this object and will affect another object reference variable.
String is a special packaging data. Can be used:
String str = new String("abc"); String str = "abc"; There are two forms to create. The first is to use new() to create a new object, which will be stored in the heap. A new object is created every time it is called.
The second type is to first create a variable str to the object of the String class in the stack, and then find out if there is "abc" stored in the stack. If not, store "abc" on the stack and let str point to "abc". If there is already "abc", directly let str point to "abc".
When comparing whether the values in the class are equal, use the equals() method; when testing whether the references of the two wrapper classes point to the same object, use ==, and use the example below to illustrate the above theory.
String str1 = "abc"; String str2 = "abc"; System.out.println(str1==str2); //true
It can be seen that str1 and str2 point to the same object.
String str1 =new String ("abc"); String str2 =new String ("abc"); System.out.println(str1==str2); // false The new method is to generate different objects. Generate one at a time.
Therefore, in the second way, multiple "abc" strings are created, and there is only one object in memory. This writing method is beneficial and saves memory space. At the same time, it can improve the running speed of the program to a certain extent, because the JVM will automatically decide whether it is necessary to create a new object based on the actual situation of the data in the stack. For the code of String str = new String("abc");, new objects are created in the heap regardless of whether their string values are equal or not, whether it is necessary to create new objects, thereby increasing the burden on the program.
On the other hand, note: When we define a class using a format such as String str = "abc";, we always take it for granted that we create an object str of the String class. (Not necessarily, because if there is no in advance, it will be created. This is the creation of the object. If there is already, then point to the original object)! The object may not have been created! And maybe just point to an object that has been created previously. Only through the new() method can we ensure that a new object is created every time. Due to the immutable nature of the String class, when the String variable needs to frequently transform its value, you should consider using the StringBuffer class to improve program efficiency.