Explain the storage mechanism of Java heap memory and stack memory in detail

Heap and memory optimization today tested the automatic data collation function of a project, collating tens of thousands of records and pictures in the database. The operation is close to the end, and Java Lang.outofmemoryerror is an error in Java heap space. In the past, this kind of memory error was rarely encountered in writing programs. Because Java has a garbage collector mechanism, it has not been paid much attention. I found some information on the Internet today and sorted it out on this basis.

1、 Heap and stack

Heap - created with new, and the garbage collector is responsible for recycling

1. When the program starts running, the JVM gets some memory from the OS, part of which is heap memory. Heap memory is usually arranged upward at the bottom of the storage address.

2. The heap is a "runtime" data area, and the objects instantiated by the class allocate space from the heap;

3. The allocated space on the heap is established through "new" and other instructions. The heap is the dynamically allocated memory size, and the lifetime does not need to be told to the compiler in advance;

4. Different from C + +, Java automatically manages the heap and stack, and the garbage collector can automatically recycle the heap memory that is no longer used;

5. The disadvantage is that memory access is slow due to the dynamic allocation of memory at run time.

Stack - store basic types and reference types, fast

1. The first in and last out data structure is usually used to save the parameters and local variables in the method;

2. In Java, variables of all basic types (short, int, long, byte, float, double, Boolean, char) and reference types are stored in the stack;

3. The living space of data in the stack is generally within the current scopes (by {...} Enclosed area;

4. The access speed of stack is faster than that of heap, second only to registers directly located in CPU;

5. The data in the stack can be shared, and multiple references can point to the same address;

6. The disadvantage is that the data size and lifetime of the stack must be determined and lack of flexibility.

2、 Memory settings

1. View virtual machine memory

By default, maxcontrol of Java virtual machine = 66650112b = 63.5625m;

In the case of doing nothing, the currentuse measured on my machine = 5177344b = 4.9375m;

2. Commands for setting memory size

-XMS < size > set initial Java heap size: sets the JVM initialization heap memory size; This value can be set to the same value as - Xmx to avoid the JVM reallocating memory after each garbage collection.

-Xmx < size > set maximum Java heap size: sets the maximum heap memory size of the JVM;

-XMN < size >: set the size of the younger generation. The whole heap size = the size of the younger generation + the size of the older generation + the size of the persistent generation.

-XSS < size > set java thread stack size: sets the memory size of JVM thread stack; 3. Specific operations (1) JVM memory setting: open MyEclipse (eclipse) window - preferences - Java - installed jres - Edit - default VM arguments and enter: - xmx128m - xms64m - xmn32m - xss16m in the VM argument

(2) IDE memory settings:

Myeclipse.com in the MyEclipse root directory Ini (or eclipse.ini in the root directory of eclipse), modify the configuration under - vmargs:

(3) Tomcat memory settings

Open the bin folder under the root directory of Tomcat and edit Catalina bat

Modify to: set Java_ OPTS= -Xms256m -Xmx512m

3、 Outofmemoryerror error analysis in Java heap

When the JVM starts, the heap memory set by the - XMS parameter is used. As the program continues to create more objects, the JVM begins to expand heap memory to accommodate more objects. The JVM also uses the garbage collector to reclaim memory. When the maximum heap memory set by - Xmx is almost reached, the JVM will throw Java. Exe if there is no more memory to allocate to the new object Lang. outofmemoryerror, the program will go down. Before throwing outofmemoryerror, the JVM will try to use the garbage collector to free up enough space, but it will throw this error when it finds that there is still not enough space. In order to solve this problem, you need to know the information of program objects, such as which objects you created, how much space which objects occupy, and so on. You can use profiler or heap analyzer to handle outofmemoryerror errors. "Java. Lang. outofmemoryerror: Java heap space" indicates that the heap does not have enough space and cannot be expanded further. " java. Lang. outofmemoryerror: permgen space "means that the permanent generation is full, and your program can no longer load classes or allocate a string.

4、 Heap and garbage collection

We know that objects are created in heap memory. Garbage collection is a process that clears dead objects out of heap space and returns these memory to the heap. In order to be used by the garbage collector, the heap is mainly divided into three areas, namely new generation, old generation or tenured generation, and perm space. New generation is the space used to store new objects. It is used when new objects are created. If they are still used for a long time, they will be moved by the garbage collector to old generation (or tenured generation). Perm space is the place where the JVM stores meta data, such as class, method, string pool and class level details.

5、 Summary:

1. Java heap memory is a part of the memory allocated by the operating system to the JVM.

2. When we create objects, they are stored in Java heap memory.

3. In order to facilitate garbage collection, the Java heap space is divided into three areas: new generation, old generation or tenured generation, and perm space.

4. You can adjust the size of Java heap space by using the JVM command line options - XMS, - Xmx, - XMN.

5. You can use jconsole or runtime maxMemory(),Runtime. totalMemory(),Runtime. Freememory() to view the size of heap memory in Java.

6. You can use the command "jmap" to obtain heap dump and "jhat" to analyze heap dump.

7. Java heap space is different from stack space. Stack space is used to store call stack and local variables.

8. The Java garbage collector is used to reclaim the memory occupied by dead objects (objects that are no longer used) and release them into the Java heap space.

9. When encountering Java When lang.outofmemoryerror, don't be nervous. Sometimes you can just increase the heap space, but if it often occurs, you need to see if there is a memory leak in the Java program.

10. Use profiler and heap dump analysis tools to view the Java heap space and how much memory is allocated to each object.

Detailed explanation of stack storage

Java stack storage has the following characteristics:

1、 The size and life cycle of the data in the stack must be determined.

For example, basic type storage: int a = 1; This variable stores literals. A is a reference to type int and points to the literal of 3. The size and lifetime of these literal values are known (these literal values are fixed in a program block, and the literal values disappear after the program block exits). For the sake of speed, they exist in the stack.

2、 Data stored in the stack can be shared.

(1) Basic type data storage:

For example:

The compiler processes int a = 3 first; First, it will create a reference with variable a in the stack, and then find out whether there is an address with literal value of 3. If not, it will open up an address with literal value of 3, and then point a to the address of 3. Then process int b = 3; After creating the reference variable of B, since there is already 3 in the stack, B will directly point to the address of 3. In this way, both a and B point to 3 at the same time.

Note: this literal reference is different from the class object reference. Assuming that the references of two class objects point to an object at the same time, if an object reference variable modifies the internal state of the object, the other object reference variable immediately reflects the change. On the contrary, modifying its value through a reference to a literal will not cause the value of another reference to this literal to change. As in the above example, after defining the values of a and B, let a = 4; So, B won't be equal to 4 or 3. Inside the compiler, a = 4 is encountered; When, it will re search whether there is a literal value of 4 in the stack. If not, it will re open the address to store the value of 4; If you already have, point a directly to this address. Therefore, the change of a value will not affect the value of B.

(2) . packaging data storage:

Such as integer, double, string and other classes that wrap the corresponding basic data types. All these class data exist in the heap. Java uses a new () statement to tell the compiler that it is dynamically created as needed at runtime. Therefore, it is more flexible, but it takes more time.

For example, take string as an example.

String is a special wrapper class data. That is, you can use string STR = new string ("ABC"); You can also use string STR = "ABC"; In the form of. The former is a standard class creation process, that is, in Java, everything is an object, and an object is an instance of a class, all created in the form of new (). Some classes in Java, such as dateformat class, can return a newly created class through the getInstance () method of this class, which seems to violate this principle. It's not. This class uses the singleton pattern to return an instance of the class, but this instance is created inside the class through new (), and getInstance () hides this detail from the outside.

Then why string STR = "ABC"; In, the instance is not created through new (), which violates the above principle? Not really.

Internal work on string STR = "ABC". Java converts this statement into the following steps: A. first define an object reference variable named STR to the string class: String str; B. find out whether there is an address with a storage value of "ABC" in the stack. If not, create an address with a storage literal value of "ABC", then create a new string class object o, point the string value of O to this address, and note the referenced object o next to this address in the stack. If there is already an address with the value "ABC", find the object o and return the address of O. c. Point STR to the address of object o. It is worth noting that the string values in the string class are usually stored directly. But like string STR = "ABC"; In this case, the string value stores a reference to the data stored in the stack (i.e. string STR = "ABC"; both stack storage and heap storage).

In order to better illustrate this problem, we can verify it through the following code.

(true is returned only if both references point to the same object. Do STR1 and STR2 both point to the same object)

The result shows that the JVM creates two references STR1 and STR2, but only one object is created, and both references point to this object.

That is to say, the change of assignment results in the change of class object reference. STR1 points to another new object, while STR2 still points to the original object. In the above example, when we change the value of STR1 to "BCD", the JVM finds that there is no address to store the value in the stack, so it opens up this address and creates a new object, and its string value points to this address.

In fact, the string class is designed to be immutable. If you want to change its value, you can, However, the JVM quietly creates a new object according to the new value at runtime (it can't change its value based on the original memory), and then returns the address of the object to the reference of the original class. Although this creation process is completely automatic, it takes more time after all. In an environment sensitive to time requirements, it will have some adverse effects.

The reference to the object str3 points directly to the object STR1 points to (note that str3 does not create a new object). After STR1 changes its value, create a string reference str4 and point to the new object created by STR1 changing the value. It can be found that str4 does not create a new object this time, so as to realize the data sharing in the stack again.

Two references were created. Two objects were created. Two references point to two different objects.

Two references were created. Two objects were created. Two references point to two different objects.

The above two sections of code show that as long as new () is used to create a new 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 be shared with the data in the stack.

Summary:

(1) we are using string STR = "ABC"; When defining the class in the format of, we always take it for granted that we have created the object STR of the string class. Worry about the trap! Object may not have been created! The only certainty is that a reference to the string class has been created. Whether the reference points to a new object or not must be considered according to the context, unless you explicitly create a new object through the new () method. Therefore, it is more accurate to say that we have created a reference variable STR pointing to the object of the string class, which points to a string class with a value of "ABC". A clear understanding of this is very helpful to eliminate the bugs that are difficult to find in the program.

(2) use string STR = "ABC"; It can improve the running speed of the program to a certain extent, because the JVM will automatically decide whether it is necessary to create a new object according to the actual situation of the data in the stack. For string STR = new string ("ABC"); Code, all new objects are created in the heap, regardless of whether their string values are equal or not, and whether it is necessary to create new objects, which increases the burden of the program.

(3) due to the immutable nature of string class (because the value of packing class cannot be modified), when the value of string variable needs to be changed frequently, StringBuffer class should be considered to improve program efficiency.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>