JVM manages two types of memory, heap and non-heap. The heap is for developers to use, as mentioned above, it is created when the JVM starts; the non-heap is reserved for the JVM itself to store class information. It is different from the heap. GC will not release space during runtime.
1. Memory overflow type
1. java.lang.OutOfMemoryError: PermGen space
JVM manages two types of memory, heap and non-heap. The heap is for developers to use, as mentioned above, it is created when the JVM starts; the non-heap is reserved for the JVM itself to store class information. It is different from the heap. GC will not release space during runtime. If the web app uses a large number of third-party jars or the application has too many class files and the MaxPermSize setting happens to be small, exceeding the limit will also cause the memory to occupy too much and cause overflow, or the tomcat will not clean up the front during hot deployment. The loaded environment will only change the context to the newly deployed one, and there will be more and more non-stacking content.
The full name of PermGen space is Permanent Generation space, which refers to the permanent storage area of memory. This memory is mainly used by the JVM to store Class and Meta information. Class will be placed in the PermGen space when it is loaded by Loader, and it stores class instances. (Instance) Heap area is different, GC (Garbage Collection) will not clean up the PermGen space during the running of the main program, so if your application has a lot of CLASS, PermGen is likely to appear. space error, this error is common when the web server pre-compiles JSP. If your WEB APP uses a large number of third-party jars, and their size exceeds the default size of the jvm (4M), this error message will be generated.
A best configuration example: (After verification by myself, since using this configuration, Tomcat has never died again)
set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
Under Linux, add a line of code as shown in red in tomcathome/conf/catalina.sh: you can increase the memory of tomcat jvm, so that memory overflow is less likely to occur!
# ----- Execute The Requested Command ---------------------------------------- -
JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"
# Bugzilla 37848: only output this if we have a TTY
2. java.lang.OutOfMemoryError: Javaheap space
The first situation is a supplement, and the main problem occurs in this situation. Its default space (i.e. -Xms) is 1/64 of the physical memory, and the maximum space (-Xmx) is 1/4 of the physical memory. If less than 40% of the memory remains, the JVM will increase the heap to the value set by Xmx. If the memory remaining exceeds 70%, the JVM will decrease the heap to the value set by Xms. Therefore, the Xmx and Xms settings of the server should generally be set the same to avoid adjusting the size of the virtual machine heap after each GC. Assuming that the physical memory is infinite, the maximum JVM memory depends on the operating system. Generally, the 32-bit machine is between 1.5g and 3g, while the 64-bit machine has no limit.
Note: If Xms exceeds the Xmx value, or the sum of the maximum heap value and the maximum non-heap value exceeds the maximum limit of physical memory or the operating system, the server will not start.
The role of garbage collection GC
The frequency of JVM calling GC is still very high, and garbage collection is performed in two main situations:
When the application thread is idle; the other is when the Java memory heap is insufficient, the GC will be continuously called. If continuous recycling cannot solve the problem of insufficient memory heap, an out of memory error will be reported. Because this exception depends on the system operating environment, it is impossible to predict when it will occur.
According to the GC mechanism, the running of the program will cause changes in the system operating environment, increasing the chance of GC triggering.
In order to avoid these problems, the design and writing of programs should avoid the memory occupation of garbage objects and the overhead of GC. Explicitly calling System.GC() can only suggest that the JVM needs to recycle garbage objects in memory, but it does not have to be recycled immediately.
One is that it cannot solve the problem of running out of memory resources, and it will also increase GC consumption.
2. Composition of JVM memory area <BR>Simply talk about the heap and stack in java
Java divides memory into two types: one is stack memory and the other is heap memory.
1. Basic type variables and object reference variables defined in the function are allocated in the stack memory of the function;
2. Heap memory is used to store objects and arrays created by new. When a variable is defined in a function (code block), Java allocates memory space for the variable on the stack. When the scope of the variable is exceeded, Java will automatically release it. Remove the memory space allocated for the variable; the memory allocated in the heap is managed by the automatic garbage collector of the Java virtual machine. The advantage of the heap is that the memory size can be dynamically allocated, and the lifetime does not need to be told to the compiler in advance, because it is in Memory is dynamically allocated at runtime. The disadvantage is that memory must be dynamically allocated at runtime, and the access speed is slow;
The advantage of the stack is that the access speed is faster than that of the heap. The disadvantage is that the size and lifetime of the data stored in the stack must be deterministic and inflexible.
The java heap is divided into three areas: New, Old and Permanent
GC has two threads:
Newly created objects are allocated to the New area. When the area is filled, it will be moved to the Old area by the GC auxiliary thread. When the Old area is also filled, the GC main thread will be triggered to traverse all objects in the heap memory. The size of the Old area is equal to Xmx minus -Xmn
Java stack storage stack adjustment: The parameters are +UseDefaultStackSize -Xss256K, which means that each thread can apply for 256k stack space. Each thread has its own Stack.
3. How to set virtual memory in JVM <BR>Tip: In JVM, if 98% of the time is used for GC and the available Heap size is less than 2%, this exception message will be thrown.
Tip: The maximum Heap Size should not exceed 80% of the available physical memory. Generally, the -Xms and -Xmx options should be set to the same value, and -Xmn should be 1/4 of the -Xmx value.
Tip: The initial memory allocated by the JVM is specified by -Xms, and the default is 1/64 of the physical memory; the maximum memory allocated by the JVM is specified by -Xmx, and the default is 1/4 of the physical memory.
By default, when the free heap memory is less than 40%, the JVM will increase the heap until the maximum limit of -Xmx; when the free heap memory is greater than 70%, the JVM will reduce the heap until the minimum limit of -Xms. Therefore, the server generally sets -Xms and -Xmx to be equal to avoid adjusting the heap size after each GC.
Tip: Assuming that the physical memory is infinite, the maximum value of JVM memory has a great relationship with the operating system.
To put it simply, although a 32-bit processor has a controllable memory space of 4GB, the specific operating system will impose a limit.
This limit is generally 2GB-3GB (generally speaking, it is 1.5G-2G under Windows systems and 2G-3G under Linux systems), and there will be no limit for processors above 64bit.
Note: If Xms exceeds the Xmx value, or the sum of the maximum heap value and the maximum non-heap value exceeds the maximum limit of physical memory or the operating system, the server will not start.
Tip: Set NewSize and MaxNewSize to be equal, and the size of "new" should not be larger than half of "old". The reason is that if the old area is not large enough, the "main" GC will be triggered frequently, which greatly reduces the performance.
JVM uses -XX:PermSize to set the initial value of non-heap memory. The default is 1/64 of physical memory;
The maximum non-heap memory size is set by XX:MaxPermSize. The default is 1/4 of the physical memory.
Solution: Manually set Heap size
Modify TOMCAT_HOME/bin/catalina.bat
Add the following lines above "echo "Using CATALINA_BASE: $CATALINA_BASE"":
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
4. Use performance check tools to locate memory leaks:
The JProfiler tool is mainly used to check and track the performance of systems (limited to Java development). JProfiler can monitor the JVM operation and performance by constantly monitoring the system's memory usage, garbage collection, thread running status and other means at any time.
1. The memory of the application server is unreasonably occupied for a long time. The memory is often occupied at a high level and is difficult to recover to a low level.