Reasons for 1.Tomcat Memory overflow
The Tomcat memory settings in the production environment are not good enough to be prone to memory overflow. Memory overflow is not the same, of course, the processing method is not the same.
Here according to the usual situation and relevant information to carry out a summary. Commonly, there are three situations:
- Outofmemoryerror:java Heap Space
- Outofmemoryerror:permgen Space
- Outofmemoryerror:unable to create new native thread.
Tomcat Memory Overflow Solution
For the first two cases, the Tomcat JVM parameters can be resolved with the application itself without a memory leak. (-xms-xmx-xx:permsize-xx:maxpermsize)
The last one may need to adjust the operating system and Tomcat JVM parameters at the same time to achieve the goal.
2, OutOfMemoryError permanent save area overflow
A. Analysis of causes:
The full name of PermGen space is permanent Generation space, which refers to the permanent storage area of memory.
This memory is primarily stored by the JVM with class and meta information, and class is placed in PermGen space when it is loader, unlike the heap area where the class instance (Instance) is stored.
GC (garbage Collection) does not clean up permgen space during the main program run time, so if you have a class in your application, you are likely to have a PermGen space error.
This error is common when the Web server pre-compile the JSP. If you have a large number of third-party jars under your web app that are larger than the JVM's default size (4M), this error message will be generated.
But this is also a problem in the current Hibernate and spring projects. It is possible that these frameworks will be dynamic class, and the JVM's GC will not clean up pemgen space, exceeding the JVM's default size (4M), causing memory overflow.
B. Recommendation:
The same third-party jar file is moved to the Tomcat/shared/lib directory, which reduces the memory consumption of the jar document.
This one is generally to increase the-xx:permsize-xx:maxpermsize to solve the problem. -xx:permsize Permanent Save Area Initial size-xx:permsize permanently save area Initial maximum value
This is typically used in conjunction with the first one, such as set java_opts=-xms1024m-xmx1024m-xx:permsize=128m-xx:permsize=256m
---------------------------------------Solution 2.1:-----------------------------------------------------
Linux servers:
The first line in catalina.sh is incremented:
java_opts=-xms64m-xmx256m-xx:permsize=128m-xx:maxnewsize=256m-xx:maxpermsize=256m
Or, add the following line above the "echo" Using catalina_base: $CATALINA _base "":
Java_opts= "-server-xx:permsize=64m-xx:maxpermsize=128m"
Windows Server:
The first line in Catalina.bat is incremented:
Set java_opts=-xms64m-xmx256m-xx:permsize=128m-xx:maxnewsize=256m-xx:maxpermsize=256m
----------------------------------------Solution 2:-------------------------------------------------------
Modify Tomcat_home/bin/catalina.bat (Linux under Catalina.sh)
"Echo" Using catalina_base: $CATALINA _base "" Add the following line above:
Set java_opts=%java_opts%-server-xx:permsize=128m-xx:maxpermsize=512m
Under catalina.sh:
java_opts= ' $JAVA _opts-server-xx:permsize=128m-xx:maxpermsize=512m '
OutOfMemoryError Heap Memory Overflow
A. Analysis of causes:
The JVM heap setting is the set of memory space that the JVM can provision in the course of running the Java program.
The JVM automatically sets the value of the heap size when it starts, and its initial space (that is,-XMS) is 1/64 of the physical memory, and the maximum space (-XMX) is 1/4 of the physical memory.
You can use options such as the-XMN-XMS-XMX provided by the JVM to set it up. The size of Heap size is the sum of young Generation and tenured generaion.
This exception information is thrown in the JVM if 98% of the time is used for GC and the available heap size is less than 2%.
The Heap Size does not exceed 80% of the available physical memory, generally the-XMS and-XMX options are set to the same, and the-XMX value of-xmn is 1/4.
-XMS: initial Heap Size
-XMX: Maximum Heap Size
However, the size of the heap is affected by the following three aspects:
1. The data model of the relevant operating system (32-BT or 64-bit) is limited, (under 32-bit systems, it is generally limited to 1.5g~2g; I tested 6g,jdk:1.6-bit operating systems under 2003 Server System (physical memory: 4G and 1612m,64) with no limit to memory. )
2. Available virtual memory limits for the system;
3. Available physical memory limits for the system.
-XMS-XMX is generally configured to be as good as set java_opts=-xms1024m-xmx1024m
Its initial space (that is,-XMS) is 1/64 of the physical memory, and the maximum space (-XMX) is 1/4 of the physical memory. Can be set with options such as-XMN-XMS-XMX provided by the JVM
B. example, the following is a reference to the parameter setting of the Java JVM in a 1G memory environment:
Java_opts= "-server-xms800m-xmx800m-xx:permsize=64m-xx:maxnewsize=256m-xx:maxpermsize=128m-djava.awt.headless= True "
Java_opts= "-server-xms768m-xmx768m-xx:permsize=128m-xx:maxpermsize=256m-xx:newsize=192m-xx:maxnewsize=384m"
Catalina_opts= "-server-xms768m-xmx768m-xx:permsize=128m-xx:maxpermsize=256m-xx:newsize=192m-xx:maxnewsize=384m "
Server is 1G RAM: java_opts= "-server-xms800m-xmx800m-xx:permsize=64m-xx:maxnewsize=256m-xx:maxpermsize=128m- Djava.awt.headless=true "
Server is 64-bit, 2G memory: java_opts= '-server-xms1024m-xmx1536m-xx:permsize=128m-xx:maxnewsize=256m-xx:maxpermsize=256m '
---------------------------------------Solution 2.1:------------------------------------------------------
Premise: Is the way to execute Startup.bat boot tomcat
Linux servers:
Catalina.sh in the/usr/local/apache-tomcat-5.5.23/bin directory
Added: java_opts= '-xms512m-xmx1024m '
or java_opts= "-server-xms800m-xmx800m-xx:maxnewsize=256m."
or catalina_opts= "-server-xms256m-xmx300m."
Windows Server:
Join at the front of the Catalina.bat
Set java_opts=-xms128m-xmx350m
or set catalina_opts=-xmx300m-xms256m
(The difference is that one directly sets the JVM memory, the other sets Tomcat memory, and Catalina_opts seems to be able to use the java_opts without distinction)
Basic parameter Description
-client,-server
Two parameters to set which run mode the virtual machine uses, as the first parameter, the client mode starts relatively fast, but the runtime performance and memory management efficiency is less efficient than the server mode, typically used for client applications.
The server mode starts slower than the client, but it can achieve higher operational performance.
On Windows, the default virtual machine type is client mode, and if you want to use server mode, you need to add the-server parameter to get higher performance on server-side applications, especially for multiple CPUs, when you start the virtual machines.
Server mode is used by default on Linux,solaris.
-xms<size>
Sets the initial size of the available memory heap for a virtual machine, which is the default unit of bytes, which is an integer multiple of 1024 and is greater than 1MB, which can be set to a large amount of memory in K (k) or M (m). The initial heap size is 2MB. Add "M" to the description is MB, otherwise it is KB.
Example:-xms6400k,-xms256m
-xmx<size>
Sets the maximum available size of the virtual machine, which is the default unit of bytes. The value must be 1024 integer multiples and be greater than 2MB. Use K (k) or M (m) to set the number of large memory units. The default heap maximum value is 64MB.
Example:-xmx81920k,-xmx80m
When an application requests a large memory runtime when the virtual machine throws a Java.lang.OutOfMemoryError:Java heap space error, it needs to use-XMX to set a large heap of available memory.
Permsize/maxpermsize: Defines the size of the perm segment, that is, the size of the permanently saved area, permsize the memory size of perm initialized when the JVM starts, and maxpermsize the maximum amount of perm memory that can be occupied.
These two values are generally set to the same on a user production environment to reduce the overhead that the system spends on memory requests during run time.
If the Tomcat,ok setting is in effect with Startup.bat startup. Enough to allocate 200M of memory successfully.
--------------------------------------Solution 2.2:-----------------------------------------------------
Premise: Is the way to execute Startup.bat boot tomcat
Manually setting the heap size
Windows Server:
To modify the Tomcat_home/bin/catalina.bat, add the following line above the "echo" Using catalina_base: $CATALINA _base "":
Set java_opts=%java_opts%-server-xms800m-xmx800m-xx:maxnewsize=256m
Note: java_opts is reserved for previous settings.
Linux servers:
Modify Tomcat_home/bin/catalina.sh
Add the following line to the "echo" Using catalina_base: $CATALINA _base "":
java_opts= "$JAVA _opts-server-xms800m-xmx800m-xx:maxnewsize=256m"
Note: $JAVA _opts is to retain the previous settings.
------------------------------------------Solution 2.3:--------------------------------------------------
Premise: Is the way that Windows system Services is executed to start Tomcat
However, if you do not execute startup.bat to start Tomcat but use Windows system services to start the Tomcat service, the settings above will not take effect.
This means that set java_opts=-xms128m-xmx350m does not work. Allocate 200M of memory above to Oom.
The Windows service performs bin\tomcat.exe. He reads the value in the registry instead of the Catalina.bat setting.
Workaround:
Modify the registry Hkey_local_machine\software\apache software Foundation\tomcat Service manager\tomcat5\parameters\javaoptions
The original value is
-dcatalina.home= "C:\ApacheGroup\Tomcat 5.0"
-djava.endorsed.dirs= "C:\ApacheGroup\Tomcat 5.0\common\endorsed"
-xrs
Join-xms300m-xmx350m
Restart Tomcat service, set to take effect
4. OutOfMemoryError cannot create a new thread
This phenomenon is relatively rare and strange, mainly related to the ratio of JVM to system memory.
This strange thing is because the JVM has been allocated a large amount of memory (such as 1.5G), and it consumes at least half of the available memory.
The greater the number of threads, the more memory you allocate to the JVM, the greater the likelihood that the above error will occur.
A. Analysis of Causes
Each 32-bit process can use up to 2G of available memory, because another 2G is reserved by the operating system. This assumes that 1.5G is used for the JVM, and then the remaining 500M of available memory.
This 500M part of the memory must be used for the load of the system DLL, then the real left is perhaps only 400M.
When you use Java to create a thread, in the JVM's memory it will also create a thread object, but it will also create a real physical thread in the operating system (refer to the JVM specification).
The operating system creates this physical thread in the remaining 400 megabytes of memory, rather than in the 1500M memory heap of the JVM.
In jdk1.4, the default stack size is 256KB, but in jdk1.5, the default stack size is 1M per thread.
Therefore, we can only create up to 400 available threads in the remaining 400M of available memory.
The conclusion is that to create more threads, you must reduce the maximum memory allocated to the JVM. Another option is to have the JVM host inside your JNI code.
Give an estimate formula for the maximum number of threads that can be created:
(maxprocessmemory-jvmmemory-reservedosmemory)/(Threadstacksize) = number of threads
For jdk1.5, assume that the operating system retains 120M of memory:
1.5GB JVM: (2GB-1.5GB-120MB)/(1MB) = ~380 threads
1.0GB JVM: (2GB-1.0GB-120MB)/(1MB) = ~880 threads
So this situation requires a combination of operating system-related adjustments, in combination with different cases of Tomcat memory allocation for different diagnoses to fundamentally solve the problem.
Detection of current JVM memory usage:
System.out.println ("JVM MAX MEMORY:" + runtime.getruntime (). MaxMemory ()/1024/1024+ "M");
System.out.println ("JVM is USING MEMORY:" + runtime.getruntime (). TotalMemory ()/1024/1024+ "M");
System.out.println ("JVM is free MEMORY:" + runtime.getruntime (). Freememory ()/1024/1024+ "M");
These three methods are all about the JVM's memory usage rather than the operating system's memory:
MaxMemory () This method returns the maximum amount of memory, in bytes, that the Java Virtual machine (the process) can construct from the operating system.
If the-XMX parameter is not added when running a Java program, then it is 64 megabytes, which means that maxmemory () returns approximately 64*1024*1024 bytes, which is the largest memory the Java Virtual machine can dig from the operating system by default.
If the-XMX parameter is added, the value following this parameter will prevail, such as JAVA-CP classpath-xmx512m ClassName, then the maximum memory is 512*1024*0124 bytes.
TotalMemory () This method returns the amount of memory that the Java Virtual machine has now dug up from the operating system, that is, all the memory occupied by the Java Virtual machine process at that time.
If you do not add-XMS parameters when running Java, then, in the Java program running process, memory is always slowly from the operating system dug, basically how much digging how much, straight to maxmemory () so far, so totalmemory () is slowly increasing.
If the-XMS parameter is used, the program will start with unconditional digging from the operating system-XMS the amount of memory defined behind it, and then dig it when the memory is about the same.
Freememory () What is it, just talked about if you run Java without adding the-XMS parameter.
In the process of running Java programs, memory is always slowly dug from the operating system, basically how much digging how much.
But in the case of Java Virtual Machine 100%, it would be a little bit more digging, and the unused memory is actually freememory ().
So the value of freememory () is generally very small, but if you are running a Java program, you use-XMS.
This time, because the program will be launched at the time of unconditional digging from the operating system-XMS the amount of memory defined behind. The memory dug up may be largely useless, so this time freememory () may be somewhat larger.
------------------------------------------------Solution------------------------------------------------------
JVM Heap Size Adjustment
Sun HotSpot 1.4.1 uses a generational collector, which divides the heap into three main domains: new, old, and permanent.
All new objects generated by the JVM are placed in the new domain. Once an object undergoes a certain number of garbage collection loops, it gets the usage period and goes into the old domain.
In a permanent domain, the JVM stores the class and method objects. In terms of configuration, a permanent domain is a separate domain and is not considered part of the heap.
The following describes how to control the size of these fields. You can use-XMS and-xmx to control the entire heap's original size or maximum value.
The following command sets the initial size to 128M:
java–xms128m
–xmx256m to control the size of the new domain, you can use-xx:newratio to set the percentage of the new domain in the heap.
The following command sets the entire heap to 128m, the new domain ratio is set to 3, that is, the new domain is proportional to the old domain 1:3, and the new domain is 1/4 or 32M of the heap:
java–xms128m–xmx128m
–xx:newratio =3 can use-xx:newsize and-xx:maxnewsize to set the initial and maximum values for the new domain.
The following command sets the initial and maximum values of the new domain to 64m:
java–xms256m–xmx256m–xmn64m
The default size of the permanent domain is 4m. When you run the program, the JVM adjusts the size of the permanent domain to suit your needs. Each time the adjustment is made, the JVM performs a full garbage collection of the heap.
Use the-XX:MAXPERSIZE flag to increase the size of the permanent domain. When the WebLogic server application loads more classes, it is often necessary to increase the maximum value of the persistent domain.
When the JVM loads a class, objects in the permanent domain increase sharply, allowing the JVM to constantly adjust the permanent domain size. To avoid adjustments, use the-XX:PERSIZE flag to set the initial value.
The following sets the permanent domain initial value to 32m and the maximum value to 64m.
java-xms512m-xmx512m-xmn128m-xx:permsize=32m-xx:maxpermsize=64m
Tomcat Memory Overflow