Heap, stack, and constant pool in Java

Source: Internet
Author: User

Java memory allocation:

1. Register: we cannot control it in the program
2. STACK: stores basic data and object references, but the object itself is not stored in the stack, but stored in the heap.
3. Heap: store data generated with new
4. static fields: static members defined by static in objects
5. Constant pool: store Constants
6. Non-RAM (random access storage) Storage: Permanent storage space such as hard disk
Bytes ----------------------------------------------------------------------------------------------------------------------

A. Some basic types of variable data defined in the function and referenced variables of the object are allocated in the function stack memory.
When a variable is defined in a code block, Java allocates memory space for the variable in the stack. When the variable exits the scope, java will automatically release the memory space allocated for the variable, and the memory space can be used for another use immediately.
B. 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, you can define a special variable 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, the variable in the stack becomes the referenced variable of the array or object. The referenced variable is equivalent to an array or an object name. Later, you can use the referenced variable in the stack in the program to access the array or object in the heap. The referenced variable is equivalent to an array or object name. The referenced variable is a common variable. It is assigned to the stack during definition. The referenced variable is released after the program runs out of its scope. Arrays and objects are allocated in the heap. Even if the program runs beyond the code block where new statements are used to generate arrays or objects, the memory occupied by arrays and objects is not released, arrays and objects become junk only when no referenced variable points to it. They cannot be used, but still occupy the memory space, the garbage collector collects (releases) the garbage collector at an uncertain time ). This is also the reason why Java accounts for memory usage.
In fact, the variables in the stack point to the variables in the heap memory. This is the pointer in Java!
C. Constant pool refers to the data that is identified during the compilation period and saved in the compiled. Class file. Besides containing the basic types (such as int and long) defined in the Code and the constant values (final) of the object type (such as string and array) it also contains some symbolic references that appear in the form of text, such as fully qualified names of classes and interfaces, field names and descriptors, methods and names and descriptors. The virtual machine must maintain a constant pool for each mounted type. A constant pool is an ordered set of constants used for this type, including direct constants (string, integer, and floating point constants) and symbolic references to other types, fields, and methods. For a String constant, its value is in the constant pool. The constant pool in JVM exists in the memory as a table. For the string type, there is a fixed-length constant_string_info table to store the text string value. Note: this table only stores text string values, but does not store symbol references. Here, we should have a clear understanding of the storage location of string values in the constant pool.

During program execution, the constant pool is stored in the method area instead of in the heap.
D. the Java heap is a runtime data zone, class (the object allocates space from it. These objects are created using commands such as new, newarray, anewarray, and multianewarray. They do not need program code to be explicitly released. The heap is responsible for garbage collection. The advantage of the heap is that the memory size can be dynamically allocated, and the lifetime does not have to be told in advance because the heap dynamically allocates memory at runtime, the Java Garbage Collector automatically collects the unused data. However, the slow access speed is due to the need to dynamically allocate memory during runtime.

The advantage of stack is that the access speed is faster than that of stack, second only to register, and stack data can be shared. However, the disadvantage is that the data size and lifetime in the stack must be fixed, and there is a lack of flexibility. The stack mainly stores some basic types of variable data (INT, short, long, byte, float, double, Boolean, char) and object handle (reference ).

A very important feature of stacks is that data in stacks can be shared. Suppose we define both:
Int A = 3;
Int B = 3;
The compiler first processes int A = 3. First, it creates a reference with the variable A in the stack, and then finds whether the value 3 in the stack exists. If no value is found, store 3 and point A to 3. Then process int B = 3. After the referenced variable of B is created, B is directed to 3 because there is already 3 in the stack. In this way, both A and B point to 3 at the same time.

At this time, if A is set to 4 again, the compiler will re-search whether there are 4 values in the stack. If not, it will store 4 and make a point to 4; if yes, direct a to this address. Therefore, changing the value of A does not affect the value of B.

Note that the sharing of data is different from the sharing of two objects pointing to one object at the same time, because the modification of a does not affect B, which is completed by the compiler, it facilitates space saving. A variable referenced by an object modifies the internal state of the object, which affects the variable referenced by another object.

/*************************************** **************************************/


String is a special packaging data. Available:
String STR = new string ("ABC ");
String STR = "ABC ";
The first method is to use new () to create an object, which is stored in the heap. Each call creates a new object.
The second method is to first create a string class object reference variable STR in the stack, and then use the symbol reference to find out whether there is "ABC" in the String constant pool. If no, store "ABC" in the String constant pool and point STR to "ABC". If "ABC" already exists, direct STR to "ABC ".

Use the equals () method to compare the values in a class. Use the = method to test whether the references of the two classes point to the same object. The example below illustrates 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 used to generate different objects. Each time one is generated.

Therefore, the second method is used to create multiple "ABC" strings, and only one object exists in the memory. this method is advantageous and saves memory space. at the same time, it can improve the program running speed to a certain extent, because the JVM will automatically decide whether 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");, a new object is created in the heap, regardless of whether the string value is equal, whether it is necessary to create a new object, this increases the burden on the program.

On the other hand, NOTE: When we define classes using formats such as string STR = "ABC";, we always take it for granted that the STR object of the string class is created. Worry trap! The object may not be created! Instead, it may only point to a previously created object. Only by using the new () method can a new object be created every time.
Because of the immutable property of the string class, when the string variable needs to change its value frequently, you should consider using the stringbuffer class to improve program efficiency.
1. First, string does not belong to eight basic data types. String is an object.
Because the default value of an object is null, the default value of string is also null, but it is a special object and has some features that other objects do not have.

2. Both new string () and new string ("") declare a new null string, which is a null string or not;

3. String STR = "kvill"; string STR = new string ("kvill ")

Example 1:

String S0 = "kvill ";
String S1 = "kvill ";
String S2 = "KV" + "ill ";
System. Out. println (S0 = S1 );
System. Out. println (S0 = S2 );

First, we need to know that Java will ensure that a String constant has only one copy.
Because "kvill" in S0 and S1 in the example are string constants, they are determined during the compilation period, so S0 = S1 is true; "KV" and "ill" are both string constants. When a string is connected by multiple string constants, it must be a String constant, so S2 is also parsed as a String constant during compilation, so S2 is also a reference of "kvill" in the constant pool. So we can get S0 = S1 = S2; the string created with new string () is not a constant and cannot be determined during the compilation period, so new string () the created strings are not placed in the constant pool. They have their own address space.

Example 2:
String S0 = "kvill ";
String S1 = new string ("kvill ");
String S2 = "KV" + new string ("ill ");
System. Out. println (S0 = S1 );
System. Out. println (S0 = S2 );
System. Out. println (S1 = S2 );

In Example 2, S0 is still a "kvill" application in the constant pool. S1 is a reference of the new object "kvill" created at runtime because it cannot be determined during the compilation period, s2 is also an application that creates the "kvill" object because it has a new string ("ill") in the second half and cannot be determined during the compilation period; if you understand this, you will know why this result is obtained.

4. String. Intern ():
Another note: the constant pool exists in the. Class file and is loaded by JVM at runtime and can be expanded. The intern () method of string is a method to expand the constant pool. When a string instance STR calls the intern () method, Java checks whether the constant pool has the same UNICODE String constant, if yes, its reference is returned. If no, a string with Unicode equal to STR is added to the constant pool and Its Reference is returned. See example 3.

Example 3:
String S0 = "kvill ";
String S1 = new string ("kvill ");
String S2 = new string ("kvill ");
System. Out. println (S0 = S1 );
System. Out. println ("**********");
S1.intern ();
S2 = s2.intern (); // assign the reference of "kvill" in the constant pool to S2
System. Out. println (S0 = S1 );
System. Out. println (S0 = s1.intern ());
System. Out. println (S0 = S2 );
False // although s1.intern () is executed, its return value is not assigned to S1
True // indicates that s1.intern () returns a reference to "kvill" in the constant pool.

Finally, let me get rid of another misunderstanding: someone says, "Use string. the intern () method can save a string class to a global string table. If a unicode string with the same value is already in this table, this method returns the address of an existing string in the table, if there is no string with the same value in the table, register the address in the table. "If I understand this global string table as a constant pool, his last sentence is, "If there is no string with the same value in the table, register your address in the table" is incorrect:

Example 4:
String S1 = new string ("kvill ");
String S2 = s1.intern ();
System. Out. println (S1 = s1.intern ());
System. Out. println (S1 + "" + S2 );
System. Out. println (s2 = s1.intern ());

In this class, we do not have a "kvill" constant, so there is no "kvill" in the constant pool at the beginning. When we call s1.intern () then, a new "kvill" constant is added to the constant pool. The original "kvill" that is not in the constant Pool still exists, so it is not "registering your own address to the constant pool.
If S1 = s1.intern () is false, the original "kvill" still exists. S2 is now the address of "kvill" in the constant pool, so S2 = s1.intern () is true.

5. About equals () and =:
In simple terms, this is to compare whether the unicode sequence of the two strings is equivalent. If the two strings are equal, true is returned, and = is to compare whether the addresses of the two strings are the same, that is, whether it is a reference to the same string.

6. the string is immutable.
This is a lot more important, as long as you know that the string instance will not change once it is generated, for example: String STR = "KV" + "ill" + "" + "Ans "; there are four string constants. First, "KV" and "ill" generate "kvill" in memory, and then "kvill" and "generate" kvill "in memory, finally, the "kvill ans" is generated, and the address of this string is assigned to STR, because the string's "immutable" produces many temporary variables, this is why stringbuffer is recommended, because stringbuffer can be changed.

/*************************************** ****************************************/

The following are some FAQs related to string:

Usage and understanding of final in string
Final stringbuffer A = new stringbuffer ("111 ");
Final stringbuffer B = new stringbuffer ("222 ");
A = B; // This sentence cannot be compiled

Final stringbuffer A = new stringbuffer ("111 ");
A. append ("222"); // compiled

It can be seen that final is only valid for the referenced "value" (that is, the memory address), which forces the reference to point only to the object initially pointed to. changing its direction will lead to compilation errors. Final is not responsible for the changes to the objects it points.

Several examples of String constant pool problems

The following is a comparative analysis and understanding of several common examples:
String A = "A1 ";
String B = "A" + 1;
System. Out. println (A = B); // result = true
String A = "atrue ";
String B = "A" + "true ";
System. Out. println (A = B); // result = true
String A = "a3.4 ";
String B = "A" + 3.4;
System. Out. println (A = B); // result = true

Analysis: JVM connects the "+" Number of string constants. During the program compilation period, the JVM optimizes the "+" connection of the constant string to the connected value, take "A" + 1 as an example. After the compiler is optimized, it is already A1 in the class. The value of its String constant is determined during compilation, so the final result of the above program is true.

String A = "AB ";
String BB = "B ";
String B = "A" + BB;
System. Out. println (A = B); // result = false

Analysis: JVM references strings. Due to the existence of string references in the "+" connection of strings, the referenced values cannot be determined during program compilation, that is, "a" + BB cannot be optimized by the compiler. It is dynamically allocated only during the running period and assigned the new connection address to B. Therefore, the result of the above program is false.

String A = "AB ";
Final string BB = "B ";
String B = "A" + BB;
System. Out. println (A = B); // result = true

Analysis: The only difference from [3] Is that the BB string is decorated with final. For final modified variables, it is parsed as a local copy of a constant value during compilation and stored in its own constant pool or embedded in its byte code stream. Therefore, "a" + BB "and" A "+" B "have the same effect. Therefore, the result of the above program is true.

String A = "AB ";
Final string BB = getbb ();
String B = "A" + BB;
System. Out. println (A = B); // result = false
Private Static string getbb (){
Return "B ";

Analysis: JVM cannot determine the value of BB in string reference during compilation. Only after the method is called during the runtime, dynamically connect the return value of the method with "A" and assign the address B. Therefore, the result of the above program is false.

The above four examples show that:
String S = "A" + "B" + "C ";
It is equivalent to string S = "ABC ";

String A = "";
String B = "B ";
String c = "C ";
String S = A + B + C;

This is different. The final result is equal:
Stringbuffer temp = new stringbuffer ();
Temp. append (a). append (B). append (C );
String S = temp. tostring ();

From the above analysis results, it is not difficult to infer the cause of the inefficiency of the string using the join operator (+), such as the Code:

Public class test {
Public static void main (string ARGs []) {
String S = NULL;
For (INT I = 0; I <100; I ++ ){
S + = "";

Every time you do the plus sign (+), a stringbuilder object is generated and then thrown away after append. When the next loop arrives, A stringbuilder object is generated again, and then the append string is generated. The loop ends until the end. If we directly use the stringbuilder object for append, we can save n-1 time to create and destroy objects. Therefore, for applications that require string connection in a loop, the append operation is generally performed using the stringbuffer or stringbulider object.

The intern method of the string object is described as follows:

Public class test4 {
Private Static string a = "AB ";
Public static void main (string [] ARGs ){
String S1 = "";
String S2 = "B ";
String S = S1 + S2;
System. Out. println (S = A); // false
System. Out. println (S. Intern () = A); // true

Java is used here as a constant pool problem. For the S1 + S2 operation, a new object is actually created in the heap, and s stores the content of the new object in the heap space, therefore, the values of S and a are not equal. When the S. Intern () method is called, the address value of S in the constant pool can be returned. Because the value of A is stored in the constant pool, the values of S. intern and a are equal.



A. the stack is used to store local variable data of the original data type and Object Reference (string, array. Object, etc.), but does not store object content.

B. objects created using the new keyword are stored in the heap.

C. A string is a special packaging class. Its reference is stored in the stack, and the object content must be determined according to the creation method (constant pool and heap ). some have been created in the compilation phase and stored in the String constant pool, while others are created during runtime. store the new keyword in the heap.


This article from: http://zy19880423.javaeye.com/blog/434179

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.