Original address: http://www.2cto.com/kf/201302/190704.html
Simply put: Java divides memory into two types: one is stack memory, and the other is heap memory.
Some of the basic types of variables and object reference variables defined in the function are allocated in the stack memory of the function. When a variable is defined in a block of code, Java allocates a memory space for the variable in the stack, and when the scope of the variable is exceeded, Java automatically frees the memory space allocated for that variable, which can be used immediately by another. Heap memory is used to hold objects and arrays created by new. The memory allocated in the heap, managed by the automatic garbage collector of the Java Virtual machine. 1. Stacks and heaps (heap) are places that Java uses to store data in RAM. Unlike C + +, Java automatically manages stacks and heaps, and programmers cannot directly set up stacks or heaps. 2. The advantage of the stack is that the access speed is faster than the heap, second only to the registers directly in the CPU. However, the disadvantage is that the size and lifetime of the data in the stack must be deterministic and inflexible. In addition, the stack data can be shared, see 3rd. The advantage of the heap is that the memory size can be allocated dynamically, and the lifetime does not have to tell the compiler beforehand that the Java garbage collector automatically collects the data that is no longer in use. However, the disadvantage is that the access speed is slower due to the dynamic allocation of memory at run time. 3. There are two kinds of data types in Java. One is the basic type (primitive types), a total of 8 kinds, namely int, short, long, byte, float, double, Boolean, char (note, and no basic type of string). The definition of this type is through such as int a = 3; Long B = 255L; the form to be defined, called an automatic variable. It is worth noting that the automatic variable is a literal value, not an instance of a class, that is not a reference to a class, there is no class here. such as int a = 3; Here A is a reference to the int type, pointing to the literal value of 3. The data of these literals, due to the size of the known, the lifetime of the known (these values are fixed in a program block, the program block exits, the field value disappears), for the sake of speed, it exists in the stack. In addition, the stack has a very important particularity, is that there is data in the stack can be shared. Suppose we define int a = 3 at the same time; int b = 3; the compiler processes int a = 3 First, it creates a reference to a variable in the stack, and then looks for an address with a literal value of 3, and then finds an address that holds the literal value of 3, and then points A to the address of 3. then the int b = 3 is processed, and after the reference variable of B is created, B is pointed directly to the address of 3 because there are already 3 literals in the stack. In this case, A and B both point to 3. Special attention, the reference to this literal is different from the reference to the class object. Assuming that a reference to two class objects points to an object at the same time, if an object reference variable modifies the internal state of the object, then another object reference variable will immediately reflect that change. Conversely, modifying its value by a reference to a literal value does not result in another case where a reference to that literal is changed. As in the example above, we define the value of a and B and then make a=4; then B will not be equal to 4 or equal to 3. Inside the compiler, when it encounters A=4, it will re-search the stack for a literal value of 4, and if not, re-open the value of the address 4, and if so, point a directly at the address. Therefore the change of a value does not affect the value of B. The other is the wrapper class data, such as Integer, String, double, and so on, the corresponding basic data types are wrapped up class. These classes of data all exist in the heap, and Java uses the new () statement to explicitly tell the compiler that it is dynamically created at run time as needed, so it is more flexible, but the disadvantage is that it takes more time. 4. String is a special wrapper class data. That is, it can be created in the form of string str = new String ("abc"), or in the form of string str = "abc" (In contrast, before JDK 5.0, you have never seen an expression of integer i = 3; because class and literal literals are not can be generic except for string. In JDK 5.0, this expression is possible! Because the compiler is converting the integer i = new Integer (3) in the background. The former is the process of creating a canonical class, that is, in Java, everything is an object, and the object is an instance of the class, all created in the form of new (). Some classes in Java, such as the DateFormat class, can return a newly created class through the class's getinstance () method, which seems to violate this principle. actually otherwise The class uses a singleton pattern to return an instance of the class, except that the instance is created inside the class through new (), and getinstance () hides this detail from the outside. So why is the case in string str = "abc", not created by new (), a violation of the above principle? Not really. 5. About the internal work of string str = "abc". Inside Java, this statement is translated into the following steps: (1) First define an object reference variable named str to the String class: String str; (2) Find the address in the stack that has a value of "ABC", and if not, open an address that holds the literal "abc". Next, create a new object of the String class O, andPoint the string value of O to the address, and note the referenced object o next to this address in the stack. If you already have an address with a value of "ABC", look for the object o and return the address of O. (3) Point Str to the address of the object o. It is important to note that the string values in the generic string class are directly stored values. But like string str = "abc"; In this case, the string value is a reference to the data in the existing stack! To better illustrate this problem, we can verify it by following several code. String str1 = "abc"; String str2 = "abc"; System.out.println (STR1==STR2); true Note that we do not use Str1.equals (STR2) in this way, as this will compare the values of two strings for equality. = = number, as described in the JDK, returns true only if two references point to the same object. And what we're looking at here is whether str1 and str2 all point to the same object. The result shows that the JVM created two references str1 and str2, but only one object was created, and two references pointed to the 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 changes in the assignment result in a change in the class object reference, and str1 points to another new object! And str2 still points to the original object. In the example above, when we change the value of str1 to "BCD", the JVM discovers that there is no address for that value in the stack, opens up this address and creates a new object whose string value points to the address. In fact, the string class is designed to be immutable (immutable) classes. If you want to change its value, yes, but the JVM silently creates a new object at run time based on the new value, and then returns the address of the object to the reference of the original class. This creation process is entirely automatic, but it takes up more time. In the environment that is more sensitive to time requirements, it will have some adverse effects. Then modify the original code: String str1 = "abc"; String str2 = "abc"; str1 = "BCD"; String STR3 = str1; System.out.println (STR3); BcdstringSTR4 = "BCD"; System.out.println (str1 = = STR4); TRUESTR3 a reference to this object points directly to the object that str1 points to (note that STR3 does not create a new object). When str1 changes its value, it creates a reference str4 of string and points to the new object created by str1 modifying the value. It can be found that this time STR4 also did not create a new object, thereby re-sharing the data in the stack. Let's look at the following code again. String str1 = new String ("abc"); String str2 = "abc"; System.out.println (STR1==STR2); False creates two references. Two objects were created. Two references point to a different two objects, respectively. String str1 = "abc"; String str2 = new String ("abc"); system.out.println (STR1==STR2); False creates two references. Two objects were created. Two references point to a different two objects, respectively. The above two code shows that as long as new () is used to create the object, it is created in the heap, and its string is stored separately, even if the data in the stack is the same, it is not shared with the data in the stack. 6. The value of the data type wrapper class cannot be modified. Not only the value of the string class cannot be modified, but all data type wrapper classes cannot change their internal values. 7. Conclusions AND Recommendations: (1) When we define a class using a format such as String str = "ABC", We always think of course that we have created the object str of the String class. Worry about traps! The object may not have been created! The only certainty is that a reference to the string class was created. As to whether the reference is pointing to a new object, it must be considered in terms of context, unless you create a new object with a prominent way through the new () method. Therefore, it is more accurate to say that we have created a reference variable to the object of the String class str, which refers to a variable that points to a string class with the value "ABC". Being aware of this is helpful in troubleshooting bugs that are difficult to find in a program. (2) The use of string str = "abc", in a way that can improve the speed of the program to a certain extent, because the JVM will automatically based on the actual data in the stack to determine whether it is necessary to create a new object. For the code of string str = new String ("abc"), it is necessary to create new objects in the heap, regardless of whether their string values are equal, toIncreased the burden on the program. This idea should be the idea of the meta-mode, but it is not known whether the internal JDK implements this pattern. (3) Use the Equals () method when comparing the values in the wrapper class, and use the = = when testing whether the references to the two wrapper classes point to the same object. (4) Because of the immutable nature of the string class, you should consider using the StringBuffer class when the string variable needs to change its value frequently to improve program efficiency. Memory allocation strategy in java and heap and stack comparison memory allocation policy according to the compiler principle, the memory allocation of the program runs three strategies, namely static, stacked, and heap. Static storage allocation is the storage space requirement at compile time to determine the time at which each data target is running. This allows them to allocate a fixed amount of memory at compile time. This allocation policy requires that the existence of mutable data structures (such as variable groups) is not allowed in the program code, and that nested or recursive structures are not allowed to appear. Because they all cause the compiler to not be able to calculate the exact storage space requirements. Stack storage allocations can also be called dynamic storage allocations, and are implemented by a stack-like run stack. Contrary to static storage allocation, in a stacked storage scenario, the requirements for the data area are completely unknown at compile time. It is only possible to know when running, but when it comes to running a program module, it is necessary to know the size of the data area required by the program module to allocate memory for it. As with the stacks we know in data structures, stack storage allocations are distributed according to the principle of advanced post-out. Static storage allocation requires that the storage requirements of all variables be known at compile time, and that the stack storage allocation requires that all storage requirements be known at the entrance of the process, while the heap storage allocation is specifically responsible for the memory allocation of the data structures that the storage requirements cannot be determined at compile-time or at runtime module entrances. such as variable-length strings and object instances. The heap consists of large chunks of available or free blocks, and the memory in the heap can be allocated and freed in any order. Heap and stack comparison the above definitions are summarized from the textbook of compiling principles, except for static storage allocations, which are inflexible and difficult to understand, leaving aside static storage allocation, Centralized comparison of heaps and stacks: from the function and function of the heap and stack to the popular comparison, the heap is mainly used to store objects, the stack is mainly used to execute the program. And this difference is mainly due to the characteristics of the heap and stack: In programming, for example, C + +, all method calls are made through stacks, all local variables, Formal parameters are allocated from the stack of memory space. It's actually not an assignment, just up the top of the stack, like a conveyor belt in the factory (conveyor belt), stack pointer will automatically guide you to where you put things, All you have to do is put things down. When you exit a function, you can change the stack pointer to the contents of the stack.Destroyed. This mode is the fastest, of course, to run the program. It is important to note that when allocating a data area for a program module that is about to be called, you should know the size of the data area beforehand, even though the allocation is performed at the time the program is run, but the size of the allocation is determined, unchanged , and this "size" is determined at compile time, not at run time. The heap is when the application is running to request the operating system to allocate its own memory, because of the memory allocation from the operating system management, so the allocation and destruction of the time to occupy, so the efficiency of the heap is very low. But the advantage of the heap is that The compiler does not have to know how much storage space to allocate from the heap, or how long the stored data will stay in the heap, so there is greater flexibility in storing the data with the heap. In fact, object-oriented polymorphism, heap memory allocation is essential, because the required storage space for polymorphic variables can only be determined after the object is created at run time. In C + +, when you require an object to be created, you only need to compile the relevant code with the new command. When you execute the code, the data is saved automatically in the heap. Of course, to achieve this flexibility, there is a certain price to pay: it will take longer to allocate storage space in the heap! This is the reason we have just said that the inefficiency of the reasons, it seems that comrade Lenin said good, people's advantages are often also human shortcomings, people's shortcomings are often people's advantages (halo ~) . The heap and stack JVM in the JVM is a stack-based virtual machine. The JVM allocates a stack for each newly created thread. In other words, for a Java program, it runs through the operation of the stack. The stack holds the state of the thread in frames. The JVM operates on the stack in only two ways: stack and stack operations in frames. We know that the method that a thread is executing 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, the JVM presses a new frame into the Java stack of threads. This frame naturally becomes the current frame. During the execution of this method, this frame is used to hold parameters, local variables, intermediate calculation procedures, and other data. This frame is similar to the concept of the activity record in the compilation principle. From this allocation mechanism in Java, the stack can be understood as a stack is a storage area that the operating system establishes for a process, or a thread (a thread in a multithreaded operating system) for this thread, which has an advanced post-out feature. Each Java application uniquely corresponds to a single JVM instance, and each instance uniquely corresponds to one heap. All instances or arrays of classes created by the application in the run are placed in this heap and shared by all threads of the application. Unlike C + +, allocating heap memory is automatically initialized in Java. The storage space for all objects in Java is allocated in the heap, but the object's reference is allocated on the stack, that is, allocating memory from two places when an object is created, the memory allocated in the heap actually establishes the object, and the memory allocated on the stack is just a pointer (reference) to the heap object. GC Considerations Why is Java slow? The existence of a JVM is of course a reason, but it is said that in Java, in addition to the simple type (Int,char, etc.) of the data structure, the other is to allocate memory in the heap (so that everything in Java is an object), which is one of the reasons for the slow program. Www.2cto.com My idea is (should be said to represent Tij's point of view), if there is no garbage Collector (GC), the above statement is set up. Heap is not like a stack is a continuous space, there is no way to expect the heap itself memory allocation can be like a stack of belt-like speed, Because, who will tidy up a huge heap of space for you, so that you have almost no delay in getting new space from the heap? This time, the GC stands out to solve the problem. We all know that GC is used to clean up the memory garbage and make room for the heap for the program, but the GC also takes on another important task. is to make the heap memory allocations in Java as fast as the memory allocations for stacks in other languages, because the problem of speed is almost unanimous to Java. To achieve this, the allocation of the heap must also be done like a conveyor belt, do not bother to find free space. In addition to clearing the garbage, the GC is responsible for organizing the objects in the heap, transferring them to a clean space far away from the garbage and arranging them in an interval that is as compact as the stack, so that the heap pointer can easily point to the starting position of the conveyor belt. Or an unused space, the next object that needs to allocate memory "directs the direction." So it can be said that garbage collection affects the speed at which objects are created, which sounds strange, right? how does the GC find all the surviving objects in the heap? As I said before, when creating an object, Allocating the actual memory of this object in the heap, and assigning a pointer (reference) to the heap object on the stack, you can trace all the surviving objects as long as the reference is found on the stack (and possibly in a static store). After they are found, the GC moves them from one heap block to the other, and Arrange them one by one, as we said above, simulate the structure of a stack, but not advanced after the allocation, but can be arbitrarily assigned, in the case of speed can be guaranteed, Isn ' t it great? but, Comrade Lenin said, People's advantages are often human shortcomings, people's shortcomings are often also the advantages of people (again dizzy ~ ~). The operation of a GC () consumes a thread, which in itself is a flaw that reduces the performance of the program, not to mention that the threadTo toss the memory over and over in the heap. Not only that, as mentioned above, the surviving objects in the heap are moved, and all references to those objects are re-assigned. This Some of these costs can result in performance degradation. The underlying data type is directly allocated in the stack space, and the form parameters of the method are allocated directly in the stack space when the method call is completed and reclaimed from the stack space. The reference data type needs to be created with new, which allocates an address space in the stack space and allocates the class variables of the object in the heap space. The reference parameter of the method, which allocates an address space in the stack space, and points to the object area of the heap space, which is reclaimed from the stack space when the method call is complete. When the local variable new comes out, allocates space in the stack space and heap space, when the local variable life cycle ends, the stack space is immediately reclaimed, and the heap space area waits for GC to reclaim. The literal parameter passed in when the method is called, first allocated in the stack space, and then allocated from the stack space after the method call is complete. String constants are allocated in the data area, this is allocated in heap space. Arrays are both allocated in the stack space and the actual size of the array is allocated in the heap space! The heap and stack &NBSP;JVM in &NBSP;JVM are stack-based virtual machines. The JVM allocates a stack for each newly created thread. In other words, for a Java program, it runs through the operation of the stack. The stack holds the state of the thread in frames. The JVM operates on the stack in only two ways: stack and stack operations in frames. We know that the method that a thread is executing 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, the JVM presses a new frame into the Java stack of threads. This frame naturally becomes the current frame. During this method execution, this frame is used to hold parameters, local variables, intermediate calculation procedures, and other data. This frame is similar to the concept of the activity record in the compilation principle here. From this allocation mechanism in Java, the stack can be understood as a stack is a storage area that the operating system establishes for a process, or a thread (a thread in a multithreaded operating system) for this thread, which has an advanced post-out feature. Each Java application uniquely corresponds to a single JVM instance, and each instance uniquely corresponds to one heap. All instances or arrays of classes created by the application in the run are placed in this heap and shared by all threads of the application. In contrast to C + +, allocating heap memory in Java is automatically initialized. The storage space for all objects in Java is allocated in the heap, but the reference to this object is allocated on the stack, that is, allocating memory from two places when an object is built, memory allocated in the heap actually establishes the object, and the memory allocated on the stack is just a pointer to the heap object (reference) Only.
gives you a thorough understanding of the differences between heap and Stack in Java