A comprehensive analysis of Java memory allocation

Source: Internet
Author: User

Reprinted from Http://blog.csdn.net/shimiso

This article introduces the principles of Java memory allocation in more detail to help beginners learn Java more easily. There are many such articles online, but most of them are rather fragmented. From the cognitive process point of view, this paper will bring the reader a systematic introduction.

The first thing to know before you get to the point is that the Java program runs on the JVM (Java Virtual Machine,java VM), which can be understood as a bridge between Java programs and operating systems, and the JVM realizes the platform independence of Java, thus the importance of the JVM. So when learning about the Java memory allocation principle, it is important to keep in mind that all this is done in the JVM, which is the basis and premise of the memory allocation principle.

In a nutshell, a complete Java program will run with the following memory areas:

L Register:JVM internal Virtual register, access speed is very fast, the program is not controllable.

L Stack: holds the value of the local variable, including: 1. The value used to hold the base data type; 2. Save an instance of the class, which is a reference (pointer) to the heap object . It can also be used to save the frame when the method is loaded.

L Heap: used to store dynamically generated data, such as new objects . Note the objects that are created contain only the member variables that belong to them, and do not include member methods. Because objects of the same class have their own member variables stored in their own heap, they share the methods of the class, and not every object is created to copy the member method one at a time.

constant Pool:The JVM maintains a constant pool for each loaded type, and a constant pool is an ordered set of constants used by this type. Includes direct constants (basic types, String) and symbolic references to other types, methods, and fields (1). The data in the pool is accessed through the same index as the array. Because a constant pool contains symbolic references to other types, methods, and fields for one type, Chang plays a central role in the dynamic linking of Java. A constant pool exists in the heap .

L Code snippet: used to store the source code read from the hard disk.

L Data segment: a static member that is used to hold a static definition.

Here is the memory representation diagram:

Roughly describes the Java memory allocation, and then through the example detailed explanation of how the Java program runs in memory (note: The film is referenced from the school horse Soldier Teacher's J2SE courseware, the right side of the diagram is the program code, the left is memory allocation, I will add comments).

Pre-Knowledge:

1. A Java file, as long as there is a main entry method, we think this is a Java program, can be compiled and run separately.

2. Whether it is a variable of a normal type or a variable of a reference type (commonly known as an instance), it can be used as a local variable, and they can all appear in the stack. Only the normal type of variable in the stack directly save its corresponding value, and the reference type of the variable is a pointer to the heap area, through this pointer, you can find this instance in the heap corresponding to the object. As a result, a normal type variable occupies only one chunk of memory in the stack, whereas a reference type variable takes up a chunk of memory in the stack area and the heap area.

Example:


1.the JVM automatically looks for the main method, executes the first sentence, creates an instance of the test class, allocates a chunk of memory on the stack, and holds a pointer to the heap area object 110925.

2. Create a variable of type int date, because it is the base type, the value of date corresponding to 9 is stored directly in the stack.

3. Create two instances of the Birthdate class D1, D2, each holding the corresponding pointers to their respective objects in the stack. They invoke a constructor with arguments when they are instantiated, so there is a custom initial value in the object.

Call the Change1 method of the test object, and use date as the argument. When the JVM reads this code, it detects that I is a local variable, so I put I in the stack and assigns the value of date to I.

Assign 1234 to I. A very simple step.

The Change1 method executes and immediately releases the stack space occupied by the local variable i.

Call the Change2 method of the test object, D1 the instance as a parameter. The JVM detects that the B parameter in the Change2 method is a local variable, is immediately added to the stack, and because it is a variable of the reference type, B holds a pointer in D1, where B and D1 point to the object in the same heap. Passing between B and D1 is a pointer.

A Birthdate object is instantiated in the Change2 method and assigned to B. The internal execution process is a new object in the heap area, and a pointer to the object is saved to the B corresponding space in the stack, and instance B no longer points to the object that the instance D1 points to, but the object pointed to by instance D1 has no change, so it cannot have any effect on D1.

The Change2 method executes and immediately releases the stack space occupied by the local reference variable B, noting that only the stack space is freed and the heap space waits for automatic recycling.

Call the Change3 method of the test instance, D2 the instance as a parameter. Similarly, the JVM allocates space in the stack for the local reference variable B, and holds the pointer in D2 in B, where D2 and B point at the same object. Invoking the Setday method of instance B is actually the Setday method of invoking the object that D2 points to.

Invoking the Setday method of instance B affects D2 because they point to the same object.

Immediately after the Change3 method is executed, the local reference variable B is released.

These are the general scenarios in which the Java program runs memory allocations. In fact, there is nothing to master the thought is very simple. There are two types of variables: the base type and the reference type. Both as local variables, are placed in the stack, the base type directly in the stack to save the value, reference type only holds a pointer to the heap area, the real object in the heap. As a parameter, the base type is passed directly to the value, and the reference type passes the pointer.

Summary:

1. distinguish what an instance is and what an object is. Class a= New Class (), at which point A is called an instance, not a is an object. The instance is in the stack, the object is in the heap, and the operation instance is actually manipulating the object indirectly through the pointer of the instance. Multiple instances can point to the same object.

2. data in the stack is not synchronized with data destruction in the heap. Once the method ends, the local variables in the stack are destroyed immediately, but the objects in the heap are not necessarily destroyed. Because there may be other variables that point to this object, it is destroyed only if there are no variables in the stack that point to the object in the heap, and it is not destroyed immediately, and can be destroyed when the garbage collection is scanned.

3. The above stacks, heaps, code snippets, data segments, and so on are all relative to the application. Each application corresponds to a unique instance of the JVM, and each JVM instance has its own area of memory that does not affect each other. And these memory areas are shared by all threads. The stacks and heaps mentioned here are concepts on the whole, and these stacks can be subdivided.

4. the member variables of a class vary in different objects and have their own storage space (the member variable is in the object in the heap). The method of the class is shared by all objects of the class, only one set, the method is pressed into the stack when the object is used, and the method does not consume memory.

The above analysis involves only stacks and heaps, and there is a very important area of memory: constant pools, where there are often inexplicable problems. What the hell is Chang? Above has been explained, there is no need to understand how deep, just remember that it maintains a loaded class of constants can be. Next, combine some examples to illustrate the characteristics of a constant pool.

Pre-Knowledge:

Wrapper classes for basic types and basic types. The basic types are: Byte, short, char, int, long, Boolean. The basic types of wrapper classes are: Byte, short, Character, Integer, Long, Boolean. Note case sensitive. The difference between the two is that the basic type is the normal variable in the program, and the basic type of wrapper class is the class, which is the reference variable in the program. Therefore, they are stored in memory in different locations: The base type is stored in the stack, and the base type wrapper class is stored in the heap. The packaging classes mentioned above all implement the constant pool technique, and the other two types of floating-point type are not implemented. In addition, the string type implements the constant pool technique.

Instance:

[Java]View Plaincopy
  1. Public class Test {
  2. public static void Main (string[] args) {
  3. Objpooltest ();
  4. }
  5. public static void Objpooltest () {
  6. int i = 40;
  7. int i0 = 40;
  8. Integer i1 = 40;
  9. Integer i2 = 40;
  10. Integer i3 = 0;
  11. Integer i4 = new Integer (40);
  12. Integer i5 = New Integer (40);
  13. Integer I6 = new Integer (0);
  14. Double d1=1.0;
  15. Double d2=1.0;
  16. System.out.println ("i=i0\t" + (i = = I0));
  17. System.out.println ("i1=i2\t" + (I1 = = i2));
  18. System.out.println ("i1=i2+i3\t" + (I1 = = i2 + i3));
  19. System.out.println ("i4=i5\t" + (i4 = = i5));
  20. System.out.println ("i4=i5+i6\t" + (I4 = = i5 + I6));
  21. System.out.println ("d1=d2\t" + (D1==D2));
  22. System.out.println ();
  23. }
  24. }

Results:

[Java]View Plaincopy
    1. I=i0 True
    2. I1=i2 True
    3. I1=i2+i3 True
    4. I4=i5 false
    5. I4=i5+i6 True
    6. D1=d2 false

Results Analysis :

1.I and I0 are variables of the normal type (int), so the data is stored directly in the stack, and the stack has an important feature: the data in the stack can be shared . When we define int i = 40, and then int i0 = 40, this time automatically checks if there is 40 of this data in the stack, and if so, I0 will point directly to the 40 of I and will not add a new 40.

2.I1 and I2 are reference types that store pointers in the stack because integer is the wrapper class. Because the integer wrapper class implements the constant pool technique, 40 of i1, I2, are all obtained from the constant pool, all pointing to the same address, so i1=12.

3. It is obvious that this is an addition operation, and thatJava's mathematical operations are performed on the stack , and thatJava automatically converts i1, i2 into integer , so that I1 is equal to I2+i3 in value.

4.i4 and i5 are reference types that store pointers in the stack because integer is the wrapper class. But since they are all new, they are no longer looking for data from the constant pool, they are new to each object from the heap, and then each hold a pointer to the object, so I4 and i5 are not equal because they have different pointers and different pointing objects.

5. This is also an addition operation, and 3 the same.

6.D1 and D2 are reference types that store pointers in the stack because double is a wrapper class. But the double wrapper class does not implement a constant pool technique, so doubled1=1.0 is equivalent to double d1=new double (1.0), which is a new object from the heap, D2 the same. So D1 and D2 hold different pointers, they point to different objects, so they are not equal.

Summary:

1. The above mentioned basic types of packaging have implemented the constant pool technology, but they maintain the constant is only "128 to 127" in the scope of the constant, if the constant value beyond this range, will be created from the heap object, no longer from the constant pool fetch. For example, change the upper example to an integer i1 = 400; Integer I2 = 400, obviously over 127, cannot get constant from the constant pool, new integer object from the heap, then I1 and i2 are not equal.

2.The string type also implements the constant pool technique, but a little bit different. The string type is the first to detect that there is no corresponding string in the constant pool, and if so, to take it out, if not, to add the current one.

All involved in memory principle, is generally broad and profound field, do not listen to opinion, read more articles. I am in this is just analysis, inside still have a lot of fishy, leave the reader to explore ponder. I hope this article can help you!

Footnote:

(1) symbol reference, as the name implies, is a symbol, the symbol reference is used when the symbol will be resolved. If you are familiar with a Linux or Unix system, you can refer to this symbolic reference as a soft link to a file, and when you use this soft connection, you will actually parse it and expand it to find the actual file.

For symbolic references, the discussion on the class loading level is much more, and the source level is just a formal discussion.

When a class is loaded, the symbolic references to other classes used by the class are saved in the constant pool, and when the actual code is executed, the JVM expands the symbolic reference for the class of the constant pool to a direct reference, so that the next time the same type is encountered, the JVM will no longer parse. and directly use this direct reference that has been parsed.

In addition to the symbolic reference of the class loading process described above, for the source level, it is according to the reference parsing process to distinguish whether some data in the code is a symbolic reference or a direct reference, such as SYSTEM.OUT.PRINTLN ("test" + "abc");// The effect that occurs here is the equivalent of a direct reference, assuming a strings = "abc"; SYSTEM.OUT.PRINTLN ("test" + s);//The effect here is equivalent to the symbolic reference, that is, the s expansion to parse, it is equivalent to S is "abc" a symbolic link, that is, at the time of compilation, the class file does not directly show the S, And this s is seen as a symbol that will unfold when the actual code is executed.

Reference article:

Java Memory allocation research: http://www.blogjava.net/Jack2007/archive/2008/05/21/202018.html

Java constant Pool A detailed comparison of the pain of the egg interview: http://www.cnblogs.com/DreamSea/archive/2011/11/20/2256396.html

JVM Constant Pool: http://www.cnblogs.com/wenfeng762/archive/2011/08/14/2137820.html

Deep Java core Java memory allocation principle explaining: http://developer.51cto.com/art/201009/225071.htm

A comprehensive analysis of Java memory allocation

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.