Let you fully understand the difference between stack and stack in JAVA

Source: Internet
Author: User

To put it simply, Java divides memory into two types: stack memory and heap memory. Variables of some basic types 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 scope of the variable is exceeded, java will automatically release the memory space allocated for the variable, and the memory space can be used for another use 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. 1. Both stack and heap are places where Java is used to store data in Ram. Unlike C ++, Java automatically manages stacks and stacks, and programmers cannot directly set stacks or stacks. 2. The advantage of stack is that the access speed is faster than the heap speed, second only to the registers directly located in the CPU. However, the disadvantage is that the data size and lifetime in the stack must be fixed, and there is a lack of flexibility. In addition, stack data can be shared. For details, refer to the 3rd point. The advantage of heap is that the memory size can be dynamically allocated, and the lifetime does not have to be told to the compiler in advance. The Java garbage collector will automatically collect the data that is no longer used. However, the slow access speed is due to the need to dynamically allocate memory during runtime. 3. There are two data types in Java. One is the basic type (primitive types). There are eight types, namely int, short, long, byte, float, double, boolean, char (note, there is no basic string type ). The definition of this type is defined in the form of int a = 3; long B = 255L;, which is called an automatic variable. It is worth noting that the automatic variable stores the literal value, not the instance of the class, that is, it is not the reference of the class, and there is no class here. For example, int a = 3; here, a is a reference pointing to the int type, pointing to the literal value of 3. Because of the size and lifetime of the nominal value data, we can see that (these nominal values are fixed in a program block, and the field value disappears after the program block exits). For the reason of speed, it exists in the stack. In addition, the stack has a very important feature, that is, data in the stack 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, then, find the address with a three-character nominal value. If the address is not found, open an address for storing the Three-character nominal value, and point a to the 3 address. Then process int B = 3. After the referenced variable of B is created, B is directed to the address of 3 because there is already 3 in the stack. In this way, both a and B point to 3 at the same time. Note that the reference of this literal value is different from that of a Class Object. Assume that the references of two class objects point to one object at the same time. If an object's reference variable modifies the internal state of the object, the variable referenced by the other object immediately reflects this change. On the contrary, modifying the value by referencing the literal value does not cause another reference value pointing to the literal value to change. In the preceding example, after defining the values of a and B, make a = 4; then, B is not equal to 4 or 3. In the compiler, when a = 4; is encountered, it will re-search whether there is a 4-character nominal value in the stack, if not, re-open the address to store the 4 value; if yes, direct a to this address. Therefore, changing the value of a does not affect the value of B. The other is the packaging class data, such as Integer, String, Double, and so on. All these class data exists in the heap. Java uses the new () statement to explicitly tell the compiler that it is dynamically created as needed during runtime, so it is flexible, however, the disadvantage is that it takes more time. 4. String is a special packaging data. You can use the String str = new String ("abc"); or the String str = "abc"; (for comparison, before JDK 5.0, you have never seen an Integer I = 3; expression, because the class and the literal value are not generic, except the String. In JDK 5.0, this expression is acceptable! Because the compiler converts Integer I = new Integer (3) in the background ). The former is the process of creating a standardized class, that is, in Java, everything is an object, and the object is a class instance, all created in the form of new. Some Classes in Java, such as the DateFormat class, can return a newly created class through the getInstance () method of the class, which seems to violate this principle. Actually not. This class uses the singleton mode to return the instance of the class, but this instance is created in the class through new (), and getInstance () hides this detail from the outside. Why didn't I use new () to create an instance in String str = "abc"; is it against the above principles? Actually no. 5. About the internal work of String str = "abc. Java internally converts this statement into the following steps: (1) first define a reference variable for the String class object named str: String str; (2) check whether there is an address with the "abc" value in the stack. If not, open an address with the "abc" value, create a new String class Object o, point the o String value to this address, and write down the referenced object o next to this address in the stack. If an address with a value of "abc" already exists, search for the object o and return the o address. (3) Point str to the address of object o. It is worth noting that the String values in the String class are stored directly. However, for example, String str = "abc"; in this case, the String value stores a reference pointing to data in the stack! To better illustrate this problem, we can use the following code for verification. String str1 = "abc"; String str2 = "abc"; System. out. println (str1 = str2); // true note: we do not use the str1.equals (str2); method here, because it will compare the values of the two strings to be equal. =. According to JDK instructions, the true value is returned only when both references point to the same object. What we need to see here is whether both str1 and str2 point to the same object. The result shows that JVM creates two references to str1 and str2, but only creates one object, and both references point to this object. Let's go further and change the above Code to: String str1 = "abc"; String str2 = "abc"; str1 = "bcd"; System. out. println (str1 + "," + str2); // bcd, abcSystem. out. println (str1 = str2); // false this means that the value assignment changes the Class Object reference, and str1 points to another object! Str2 still points to the original object. In the above example, when we change the str1 value to "bcd", the JVM opens up the address when it finds that the value is not stored in the stack, and creates a new object whose string value points to this address. In fact, the String class is designed as an immutable class. If you want to change its value, yes, but during the runtime, the JVM quietly creates a new object based on the new value, and then returns the address of this object to the reference of the original class. Although the creation process is completely automatic, it takes more time. In environments with time-sensitive requirements, there may be adverse effects. Modify the original code: String str1 = "abc"; String str2 = "abc"; str1 = "bcd"; String str3 = str1; System. out. println (str3); // bcdString str4 = "bcd"; System. out. println (str1 = str4); // a reference to the truestr3 object directs directly to the object pointed to by str1 (note that str3 does not create a new object ). After str1 has changed its value, create another String reference str4 and point it to the new object created by modifying the value of str1. It can be found that this time str4 has not created a new object, so as to share data in the stack again. Let's look at the following code. String str1 = new String ("abc"); String str2 = "abc"; System. out. println (str1 = str2); // false creates two references. Two objects are created. The two references point to two different objects. String str1 = "abc"; String str2 = new String ("abc"); System. out. println (str1 = str2); // false creates two references. Two objects are created. The two references point to two different objects. The above two sections of Code describe that as long as new () is used to create an object, it will be created in the heap, and its string is stored separately, even if it is the same as the data in the stack, it will not share data with the stack. 6. The value of the Data Type package class cannot be modified. Not only the values of the String class cannot be modified, but the internal values of all data type packaging classes cannot be changed. 7. Conclusion and Suggestion: (1) when we define a class using a format such as String str = "abc";, we always assume that we have created a String class Object str. Worry trap! The object may not be created! The only difference is that the reference to the String class is created. Whether the reference actually points to a new object must be considered based on the context, unless you explicitly create a new object through the new () method. Therefore, to be more accurate, we have created a reference variable str pointing to an object of the String class, which points to a String class with a value of "abc. It is helpful to be aware of this point to exclude bugs that are hard to be found in the program. (2) using String str = "abc"; can improve the program running speed to a certain extent, because the JVM automatically determines whether it is necessary to create a new object based on the actual 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. This idea should be about the metadata-sharing model, but it is not clear whether the internal implementation of JDK applies this model here. (3) Use the equals () method to compare the values in the packaging class. Use = to test whether the references of the two packaging classes point to the same object. (4) because of the immutable property of the String class, when the String variable needs to change its value frequently, the StringBuffer class should be considered to improve program efficiency. In java, memory allocation policies and heap and stack comparison memory allocation policies according to the compilation principle, there are three memory allocation policies for running programs: static and stack-based, and heap. static Storage Allocation refers to the ability to determine the storage space requirements of each data target at runtime during compilation. Therefore, a fixed memory space can be allocated to each data target during compilation. this allocation policy requires that the existence of a variable data structure (such as a variable array) or nested or recursive structure is not allowed in the program code, because they both cause compilation programs to fail to calculate accurate storage space requirements. stack-based storage allocation, also known as dynamic storage allocation, is implemented by a stack-like running stack. in contrast to static storage allocation, in stack-based storage solutions, the program's requirements for data areas are completely unknown during compilation and can only be known at runtime, however, when entering a program module during running, you must know the size of the Data zone required by the program module to allocate memory for it. like the stack we are familiar with in the data structure, stack-based storage allocation is distributed based on the principle of first-in-first-out. Static storage allocation requires that the storage requirements of all variables be known during compilation, and stack-based storage allocation requires that all storage requirements be known at the entrance of the process, heap Storage allocation is specifically responsible for the memory allocation of data structures that cannot be determined at the module entrance during compilation or runtime, such as variable length strings and object instances. the heap consists of a large part of available blocks or idle blocks. The memory in the heap can be allocated and released in any order. the Comparison Between heap and stack is summarized in the textbook on the Compilation Principle. Apart from static storage allocation, the definitions are rigid and hard to understand. static storage allocation is put aside below, centralized comparison of stacks and stacks: The functions and functions of stacks and stacks are commonly compared. stacks are mainly used to store objects and stacks are mainly used to execute programs. this difference is mainly determined by the features of stacks and stacks: in programming, for example, in C/C ++, all method calls are implemented through stacks, all local variables and formal parameters are allocated memory space from the stack. In fact, there is no allocation, just use it from the top of the Stack, just like a conveyor belt in the factory (conveyor belt), Stack Pointer will automatically guide you to the place where you put things, all you have to do is put things down. when you exit the function, you can modify the stack pointer to destroy the stack content. this mode is the fastest, of course, used to run the program. it should be noted that, during the allocation, for example, when assigning a data zone to a program module to be called, the size of the Data zone should be known in advance, that is to say, although the allocation is performed while the program is running, the size of the allocation is fixed, and the "size" is determined during compilation, not at runtime. heap requests the operating system to allocate memory when the application is running. Because the memory allocated is managed by the operating system, it takes time to allocate and destroy the heap, therefore, the efficiency of using the heap is very low. however, the advantage of heap is that the compiler does not have to know how much storage space is allocated from the heap or how long the stored data will stay in the heap. Therefore, storing data in a heap gives you more flexibility. In fact, heap memory allocation is essential for object-oriented polymorphism, because the storage space required for Polymorphism variables can be determined only after the object is created at runtime. in C ++, when creating an object, you only need to use the new command to compile the relevant code. When the code is executed, data is automatically saved in the heap. of course, to achieve this flexibility, you must pay a certain price: It will take longer to allocate storage space in the heap! This is exactly the reason why we have just said that the efficiency is low. It seems that comrade Lenin is good at saying that the advantages of people are also the disadvantages of people, the disadvantage of a person is often the advantage of a person (dizzy ~). The stack and stack JVM in JVM are stack-based virtual machines. JVM allocates a stack for each newly created thread. that is to say, for a Java program, its operation is done through stack operations. The stack stores the thread status in frames. JVM only performs two types of operations on the stack: frame-based stack pressure and outbound stack operations. We know that the method being executed by a thread is called the current method of this thread. We may not know that the frame used by the current method is called the current frame. When a thread activates a Java method, JVM will press a new frame into the thread's Java stack. This frame naturally becomes the current frame. during the execution of this method, this frame will be used to save parameters, local variables, intermediate calculation processes, and other data. this frame is similar to the activity record concept in the compilation principle. from the perspective of Java's allocation mechanism, the Stack can be understood as follows: a Stack is a process or thread created by the operating system (a thread in an operating system that supports multithreading) the storage area created for this thread has the advanced and later features. Each Java application corresponds to only one JVM instance, and each instance corresponds to only one heap. All the class instances or arrays created by the application during running are stored in this heap and shared by all the threads of the application. unlike C/C ++, heap memory allocation in Java is automatically initialized. In Java, the storage space of all objects is allocated in the heap, but the reference of this object is allocated in the stack. That is to say, the memory is allocated from both places when an object is created, the memory allocated in the heap actually creates this object, and the memory allocated in the stack is just a pointer (reference) pointing to this heap object. Why is GC slow in Java? The existence of JVM is certainly one reason, but some people say that in Java, apart from the data structure of simple types (int, char, etc, others are allocating memory in the heap (So everything in Java is an object), which is also one of the reasons for slow programs. Www.2cto.com my idea is (it should be said to represent TIJ's point of view). If there is no Garbage Collector (GC), the above statement is true. the heap is not like the stack is a continuous space, and there is no way to expect the heap's memory allocation to have a conveyor speed like the stack, because who will sort out the huge heap space for you, what makes you get new space from the heap with almost no latency? At this time, the GC station came out to solve the problem. we all know that GC is used to clear the memory garbage and free up space for the heap for the program. However, GC is also responsible for another important task, it is to make the heap memory allocation in Java as fast as the memory allocation in other languages, because the speed problem is almost a public criticism of Java. to achieve this goal, you must make the heap allocation the same as the conveyor belt, so you don't have to worry about finding free space. in this way, GC is not only responsible for clearing Garbage, but also responsible for organizing the objects in the heap and moving them to a pure space away from Garbage without intervals, which is as compact as in the stack, in this way, Heap Pointer can easily point to the starting position of the conveyor belt, or an unused space, and "Guiding Direction" for the next object needing to allocate memory ". so it can be said that garbage collection affects the creation speed of objects. It sounds strange, right? Then how does GC find all the surviving objects in the heap? As mentioned above, when an object is created, allocate the memory of the object actually created in the heap, and assign a pointer to the heap object in the stack (for reference ), as long as the reference is found in the stack (or in the static storage area), all the surviving objects can be tracked. after finding them, GC will move them from one heap block to another heap block and arrange them one by one, as we said above, simulate a stack structure, but it is not an advanced distribution, but can be allocated at will. When the speed can be guaranteed, isn' t it great? However, comrade Lenin said that the advantages of people are often also the disadvantages of people. The disadvantages of people are also the advantages of people (then dizzy ~~). GC () runs to occupy a thread, which is itself a defect to reduce the performance of the program, not to mention the thread also needs to overwrite the memory in the heap. not only that, as mentioned above, all references to the objects in the heap must be assigned a value. these overhead will lead to performance reduction. the basic data type is directly allocated in the stack space. The method format parameters are directly allocated in the stack space. After the method call is completed, the stack space is reclaimed. To reference the data type, you must use new to create a class variable that allocates an address space in the stack space and objects in the heap space. Method reference parameters: Allocate an address space in the stack space and point to the object area of the heap space. After the method is called, it is reclaimed from the stack space. When the local variable is new, an empty space is allocated between the stack space and the heap space. When the lifecycle of the local variable ends, the stack space is immediately reclaimed, And the heap space is waiting for GC to be recycled. The literal parameter passed in when the method is called. It is first allocated in the stack space, and then allocated from the stack space after the method is called. String constants are allocated in the DATA area, and this is allocated in the heap space. The array not only allocates the array name in the stack space, but also allocates the actual size of the array in the heap space! The stack and stack JVM in JVM are stack-based virtual machines. JVM assigns a stack to each newly created thread. That is to say, for a Java program, its operation is done through stack operations. The stack stores the thread status in frames. JVM only performs two types of operations on the stack: frame-based stack pressure and outbound stack operations. We know that the method being executed by a thread is called the current method of this thread. We may not know that the frame used in the current method is called the current frame. When a thread activates a Java method, JVM will press a new frame into the thread's Java stack. This frame naturally becomes the current frame. During the execution of this method, this frame will be used to save parameters, local variables, intermediate calculation process and other data. This frame is similar to the activity record concept in the compilation principle. From the perspective of Java's allocation mechanism, the Stack can be understood as follows: a Stack is a process or thread created by the operating system (a thread in an operating system that supports multithreading) the storage area created for this thread has the advanced and later features. Each Java application corresponds to only one JVM instance, and each instance corresponds to only one heap. All the class instances or arrays created by the application during running are stored in this heap and shared by all the threads of the application. Unlike C/C ++, heap memory allocation in Java is automatically initialized. In Java, the storage space of all objects is allocated in the heap, but the reference of this object is allocated in the stack. That is to say, the memory is allocated from both places when an object is created, the memory allocated in the heap actually creates this object, and the memory allocated in the stack is just a pointer (reference) pointing to this heap object.

Related Article

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.