Interview--Java memory Layout "diagram" and Java various storage "detailed"

Source: Internet
Author: User

First, the Java Memory Layout shallowly discusses

1. General statement

We know that threads are the basic unit of operating system scheduling. All threads share the heap space of the parent process, and each thread has its own stack space and program counters. Therefore, the Java virtual machine is also seen as a separate process, where the memory space is divided into thread-sharing space and thread-unique space. The Java Virtual machine memory layout is as follows:

2. Memory space shared by all threads

(1) heap space : The JVM specification stipulates that all object instances and arrays are allocated on the heap. In general, heap space has a default size, depending on the JVM implementation, and can be dynamically scaled as needed. An OutOfMemoryError exception is thrown when an object needs to allocate space on the heap and the heap itself is not enough space to request additional memory space.
(2) method area : Stores data such as class information , constants , and static variables that have been loaded by the JVM. The method area, like the Java heap, is an area of memory shared by each thread that stores data such as class information, constants, static variables, and code compiled by the immediate compiler that have been loaded by the virtual machine. The static domain and Chang (Runtime Constant Pool) are part of the method area.

3. Memory space unique to each thread

(1) program counter : Although many programs are multi-threaded, but because there is generally only one processor, so the current moment is only possible to execute a thread. And through the constant thread switching, it achieves a kind of multi-threaded concurrent execution illusion. If thread A is suspended when it executes to an instruction, switch to thread B. When thread B finishes executing, thread A needs to be executed, and the processor must know which instruction a thread A has executed last to recover from the break. Therefore, each thread is a program counter that represents the Java instruction address that the thread currently needs to execute (this refers to the JVM memory space address).

(2) virtual machine stack space : When the JVM executes a thread's method, it creates a stack frame for the thread method (which can be understood as a storage area in the JVM stack space). This stack frame is used to store local variable tables, operand stacks, dynamic links, and method entry information.

Java memory is often differentiated into heap memory (heap) and stack memory (stack), which is coarser, and the division of Java memory areas is actually far more complex. This Division

The popularity of the approach only shows that the memory area most closely related to object memory allocation is the two blocks most programmers care about. The "heap" referred to therein will be specifically described in the following

"Stack" is the current virtual machine stack, or the local variable table part of the virtual machine stack.

A local variable table holds variables and object references for various basic data types (Boolean, Byte, char, short, int, float, long, double) that are known at compile time.

(reference type). The object reference is not the same as the object itself, depending on the virtual machine implementation, it may be a reference pointer to the start address of the object, or it may point to an object representing the

Handle or other location associated with this object) and the ReturnAddress type (the address of a bytecode directive).

(3) local method stack space : Similar to virtual machine stack space, only used to store information about local method calls.

The local methods Stack (Native method Stacks) plays a very similar role to the virtual machine stack, except that the virtual machine stack executes Java methods for the virtual machine (that is, the word

The local method stack is the native method service that is used for the virtual machine. The language, usage, and data structures used in the virtual machine specification for methods in the local method stack are not

There are mandatory rules, so a specific virtual machine is free to implement it. Even some virtual machines, such as sun hotspot virtual machines, combine the local method stack and the virtual machine stack directly.

In short, the beginner stage can be the virtual machine stack space and the local method stack space as a unified understanding of the "stack" (and heap correspondence).

Ii. detailed data storage areas in Java

1. Register: The fastest storage area, which is allocated by the compiler according to the requirements, we can not control in the program. "I don't know because I can't control it."
2. Stack: A reference to a basic type of variable data and an object, but the object itself is not stored in the stack, but is stored in the heap (the new object) or in a constant pool (the string constant object is stored in a constant pool. )
3. Heap: Store all new objects.
4. Static domain: A static member (statically defined) "method area belonging to a space"
5. Constant pool: Holds string constants and basic type constants (public static final). "Method areas that are part of a shared space"
6. Non-RAM storage: Permanent storage space such as hard disk "no understanding"

In summary, it is sufficient to differentiate between stacks, heaps, static domains, and constant pools of four zones. Static and constant pools are often treated as a zone without distinction.

Here we are primarily concerned with stacks, heaps, and constant pools, which can be shared for objects in stacks and constant pools, and not for objects in the heap. The data size and life cycle in the stack can be determined, and the data disappears when no references point to the data. The garbage collector is responsible for the collection of objects in the heap, so the size and life cycle do not need to be determined and have great flexibility.
For strings: References to their objects are stored in the stack, and if the compilation period has been created (defined directly in double quotes), it is stored in a constant pool, which is stored in the heap if the run-time (new) is determined. For a string equal to equals, there is always only one copy in the constant pool, with multiple copies in the heap.
such as the following code:

Java code
1.String S1 = "China"; String is a constant type by default, and it can be assumed that final is omitted by default because the string content is immutable
2.String s2 = "China";
3.String s3 = "China";
4.String SS1 = new String ("China");
5.String SS2 = new String ("China");
6.String SS3 = new String ("China");
When a string is generated by new (assuming "China"), the constant pool is first searched for whether the "Chinese" object is already in use, and if none is created in the constant pool, then a copy object of this "China" object in the heap is created in a constant pool. This is the way of the interview: string s = new string ("xyz"), how many objects are produced? One or two, if there is no "xyz" in the constant pool, it is two.
For variables and constants of the underlying type: variables and references are stored in the stack, and constants are stored in the constant pool.
such as the following code:

Java code
1.int I1 = 9;
2.int i2 = 9;
3.int i3 = 9;
4.public static final int INT1 = 9;
5.public static final int INT2 = 9;
6.public static final int INT3 = 9;

For member variables and local variables: member variables are external to the method, variables defined internally by the class, and local variables are variables defined inside a method or statement block. Local variables must be initialized.
The formal parameter is a local variable, and the data for the local variable exists in the stack memory. Local variables in the stack memory disappear as the method disappears.
Member variables are stored in objects in the heap and are collected by the garbage collector.
such as the following code:

Java code
1.class BirthDate {
2. private int day;
3. private int month;
4. private int year;
5. Public BirthDate (int d, int m, int y) {
6. Day = D;
7. Month = m;
8. Year = y;
9.}
10. Omit the Get,set method ...
11.}
12.
13.public class test{
public static void Main (String args[]) {
15.int date = 9;
Test test = new test ();
Test.change (date);
BirthDate d1= New BirthDate (7,7,1970);
19.}
20.
. public void Change1 (int i) {
i = 1234;
23.}
For this code, date is a local variable, i,d,m,y is a local variable, and Day,month,year is a member variable. The following analysis of the code execution time changes:
1. The main method begins execution: int date = 9;
Date local variables, underlying types, references, and values are present in the stack.
2. Test test = new test ();
Test is an object reference, exists in the stack, and the object (new Test ()) exists in the heap.
3. Test.change (date);
I is a local variable, and the reference and value exist in the stack. When the method change execution is complete, I will disappear from the stack.
4. BirthDate d1= new BirthDate (7,7,1970);
D1 is an object reference, exists in the stack, the object (new BirthDate ()) exists in the heap, where D,m,y is stored in the stack for local variables, and their type is the underlying type, so their data is also stored in the stack. Day,month,year are member variables that are stored in the heap (new BirthDate ()). When the birthdate construction method finishes executing, the d,m,y disappears from the stack.
After the 5.main method executes, the date variable, TEST,D1 reference will disappear from the stack, new test (), new BirthDate () will wait for garbage collection.

Third, add the difference between stack and heap:

The Java heap is a run-time data area in which objects allocate space. These objects are established through directives such as new, NewArray, Anewarray, and Multianewarray, and they do not require program code to be explicitly released. Heap is responsible for garbage collection, the advantage of the heap is the ability to dynamically allocate memory size, the lifetime does not have to tell the compiler beforehand, because it is at runtime to allocate memory dynamically, Java garbage collector will automatically take away these no longer use data. However, the disadvantage is that the access speed is slower due to the dynamic allocation of memory at run time.

The advantage of the stack is that the access speed is faster than the heap, after the register, the stack data can be shared . However, the disadvantage is that the size and lifetime of the data in the stack must be deterministic and inflexible. The stack mainly contains some basic types of variable data (int, short, long, byte, float, double, Boolean, char) and object handle (reference).

Stack has a very important particularity, is that there is data in the stack can be shared. Let's say we define both:

Java code

int a = 3;

int b = 3; The essence of these two sentences is that only one memory space is allocated to the stack, storing 3, except that the memory space has two aliases, A and B, respectively. "

The compiler processes int a = 3 First, it creates a reference to a variable in the stack, and then finds out if there is a value of 3 in the stack, and if it does not, it stores the 3 in and then points a to 3. then the int b = 3 is processed, and after the reference variable of B is created, because there are already 3 values in the stack, B points directly to 3. In this case, A and B both point to 3.

At this point, if you make a=4 again, then the compiler will re-search the stack for 4 values, if not, then store 4 in, and a point to 4; Therefore the change of a value does not affect the value of B.

It is important to note that this sharing of data with two object references also points to an object where this share is different, because the modification of a does not affect B, which is done by the compiler, which facilitates space saving. An object reference variable modifies the internal state of the object, affecting another object reference variable.

Iv. Several examples of string constant pool problems

Example 1:

Java code

String s0= "Kvill";

String s1= "Kvill";

String s2= "kv" + "ill";

System.out.println (S0==S1);

System.out.println (S0==S2);

The result is:

True

True

Analysis: First, we need to know that the result is that Java ensures that a string constant has only one copy.

Because the "Kvill" in S0 and S1 in the example are string constants, they are determined at compile time, so s0==s1 is true, and "kv" and "ill" are also string constants, and when a string is concatenated by multiple string constants, it is itself a string constant. So S2 is also parsed as a string constant at compile time, so S2 is also a reference to "Kvill" in the constant pool. So we come to s0==s1==s2;

Example 2:

Example:

Java code

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);

The result is:

False

False

False

Parsing: strings created with new string () are not constants and cannot be determined at compile time, so the strings created by new string () are not placed in the constant pool, they have their own address space.

S0 is also an application of "Kvill" in a constant pool, s1 because it cannot be determined at compile time, it is a reference to the new object "Kvill" created at run time, S2 because there is a second half part new String ("ill") so it cannot be determined at compile time, so it is also a newly created object "Kvill" The application of the same, and understand that this will know why the result is reached.

Example 3:

Java code

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 for string constant "+" number connection, the program compile period, the JVM will be the constant string "+" connection optimization to the concatenated value, take "a" + 1, the compiler is optimized in class is already A1. The value of its string constants is determined at compile time, so the final result of the above program is true.

Example 4:

Java code

String a = "AB";

String BB = "B";

String B = "a" + BB;

System.out.println ((A = = b)); result = False

Analysis: JVM for string reference, because in the string "+" connection, there is a string reference exists, and the reference value in the program compilation period is not determined, that is, "a" + BB can not be optimized by the compiler, only during the program run time to dynamically allocate and the new address after the connection to B. So the result of the above program is also false.

Example 5:

Java code

String a = "AB";

Final String bb = "B";

String B = "a" + BB;

System.out.println ((A = = b)); result = True

Analysis: The only difference between [4] is that the BB string has a final decoration, and for a final modified variable, it is parsed at compile time to a local copy of the constant value stored in its own constant pool or embedded in its byte stream. So at this point the "a" + BB and "a" + "B" effect is the same. Therefore, the result of the above program is true.

Example 6:

Java code

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: The JVM for the string reference BB, its value in the compilation period can not be determined, only after the program run time call method, the return value of the method and "a" to dynamically connect and assign the address to B, so the result of the above program is false.

About string is immutable

From the above example, we can tell:

String s = "a" + "B" + "C";

is equivalent to string s = "abc";

String a = "a";

String B = "B";

String c = "C";

String s = a + B + C;

This is not the same, the end result equals:

Java code

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 that the string using the Join operator (+) inefficiency reason analysis, such as the code:

Java code

public class Test {

public static void Main (String args[]) {

String s = null;

for (int i = 0; i <; i++) {

s + = "a";

}

}

}

Every time you do it, you produce a StringBuilder object and then throw it away after append. The next time the loop arrives, it re-generates the StringBuilder object and then append the string so that it loops until the end. If we use the StringBuilder object directly for Append, we can save N-1 time to create and destroy objects. So for applications that want to concatenate strings in a loop, the StringBuffer or Stringbulider objects are generally used for append operations.

Because of the immutable nature of the string class, this is said a lot, as long as we know that the string instance once generated will not be changed, such as: string Str= "kv" + "ill" + "+" ans "; There are 4 string constants, first "KV" and "ill" generate "Kvill" in memory, and then "Kvill" and "Generate" Kvill "in memory, and finally generated" Kvill ans ", and the address of the string to the STR, This is because the "immutable" of string produces a lot of temporary variables, which is why it is recommended to use StringBuffer, because StringBuffer can be changed.

Final usage and understanding in string

Java code

Final StringBuffer a = new StringBuffer ("111");

Final StringBuffer B = new StringBuffer ("222");

a=b;//This sentence compilation does not pass

Final StringBuffer a = new StringBuffer ("111");

A.append ("222");//Compile Through

As you can see, final is valid only for the reference "value" (that is, the memory address), which forces the reference to point only to the object that was initially pointed to, and changes its point to cause a compile-time error. Final is not responsible for the change in the object it points to.

Summarize

  A reference to the local variable data and objects (String, Array, object, and so on) that are used to hold some raw data types in the stack. But not the object content

The heap contains objects created using the New keyword.

A string is a special wrapper class whose reference is stored in the stack, and the object content must be set differently (Chang and heap) depending on how it was created. Some compile time has been created, stored in a string constant pool, and some runtime is created. Use the new keyword to store in the heap.

La La la

Interview--Java memory Layout "diagram" and Java various storage "detailed"

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.