Tomcat Memory leak Solution
This kind of problem is often encountered in the development, see the experience of the predecessors
Reasons for Tomcat Memory overflow
In a production environment, Tomcat memory settings 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:
1.outofmemoryerror:java Heap Space
2.outofmemoryerror:permgen Space
3.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.
The first: a heap overflow.
Cause Analysis:
The JVM heap setting is the set of memory space that the JVM can provision during the run of 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.
In the absence of a memory leak, the tuning-xms-xmx parameter can be resolved.
-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.
The heap size can be tested using the JAVA-XMX***M version command. Support will appear the JDK version number, does not support error.
-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. You can use options such as the-XMN-XMS-XMX provided by the JVM to
To set
example, the following is a reference to the parameter settings for a 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 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
These two parameters are used to set the operating mode used by the virtual machine and must be the first parameter, the client mode starts relatively fast, but the runtime performance and memory management efficiency is less efficient than the server mode, which is typically used for client applications. In contrast, 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.
In addition, under multiple cups, it is recommended to use the server mode
-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:------------------------
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 "":
Java code
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 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
-------------------Solution 4:-----------------------------
Premise: Is the way that Windows system Services is executed to start Tomcat
If you check "NT Service (NT/2000/XP only)" When installing Tomcat
After the installation is complete, there will be a tomcat.exe file in the "bin" Directory of the installation directory.
Stop the Tomcat service first.
In command-line mode (input cmd in run)
Switch directories to the Tomcat bin directory
Use the following command to remove the service
Tomcat-uninstall "Apache Tomcat 4.1"
Next, write a batch process.
The contents are as follows
Set Servicename=apache Tomcat 4.1
Set Catalina_home=e:\tomcat 4.1.24
Set Classpath=d:\j2sdk1.4.1_01\lib
Set javaclasspath=%classpath%
Set javaclasspath=%javaclasspath%;? Talina_home%\bin\bootstrap.jar
Set javaclasspath=%javaclasspath%;? Talina_home%\common\lib\servlet.jar
Set Javaclasspath=%javaclasspath%;%java_home%\lib\tools.jar
Tomcat.exe-install "%servicename%" "%java_home%\jre\bin\server\jvm.dll"-djava.class.path= "%JAVACLASSPATH%"- Dcatalina.home= "? Talina_home% "-xms512m-xmx768m-start org.apache.catalina.startup.bootstrap-params start-stop Org.apache.catalina.startup.bootstrap-params stop-out "? Talina_home%\logs\stdout.log "-err"? Talina_home%\logs\stderr.log "
Note that the last line starts from Tomcat.exe-install! Do not manually enter the line to break the line into several paragraphs. After saving, execute the bat file at the command line, and note that the Services window is closed when it is executed.
The second type: Permanent save area overflow
Cause Analysis:
PermGen space is the full name of permanent Generation space, refers to the memory of the permanent storage area, this block of memory is mainly stored by the JVM class and meta information, class is loader will be placed in PermGen Space, unlike the heap area where the class instance (Instance) is stored, the GC (garbage Collection) does not clean up permgen space during the main program run time, so if you have a class in your application, PermGen space errors are most likely to occur 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.
Recommendation: Move the same third-party jar files to the Tomcat/shared/lib directory, which can reduce 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 the initial maximum value of the permanently saved area
This is typically used in conjunction with the first one, such as set java_opts=-xms1024m-xmx1024m-xx:permsize=128m-xx:permsize=256m
One thing to note: The java-xmx***m version command to test the maximum heap memory is-xmx with-xx:permsize and for example the system supports the largest JVM heap size thing 1.5G, that-xmx1024m-xx:permsize=768m is not able to run.
-----------------Solution 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 to 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), in Java code
"Echo" Using catalina_base: $CATALINA _base "" Add the following line above:
Set java_opts=%java_opts%-server-xx:permsize=128m-xx:maxpermsize=512m
"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 code
java_opts= "$JAVA _opts-server-xx:permsize=128m-xx:maxpermsize=512m"
java_opts= "$JAVA _opts-server-xx:permsize=128m-xx:maxpermsize=512m"
Third: You 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. It has been found that the more memory you allocate to the JVM, the greater the likelihood that the above error will occur, given the large number of threads.
Cause analysis
(From this blog to understand the reason: http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html):
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 to load the system DLL, then the real left is perhaps only 400M, and now the key point arises: When you use Java to create a thread, in the JVM's memory will also create a thread object, But it also creates a real physical thread in the operating system (referencing the JVM specification), and the operating system creates the 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, so we can 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
In 2000/xp/2003 's boot. INI, there is a boot option, as if:/pae/3g, which allows the user process to expand the maximum memory to 3G, when the operating system can only occupy up to 1G of virtual storage. That should allow the JVM to create more threads.
So this situation needs to be adjusted in conjunction with the operating system.
Therefore: we need to diagnose the Tomcat memory allocation differently in combination with different scenarios 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, not the operating system's memory;
MaxMemory () This method returns the maximum amount of memory that the Java Virtual machine (this process) can construct from the operating system, in bytes, if the Java program is running without adding the-XMX parameter, then it is 64 trillion, which means maxmemory () The return is approximately 64*1024*1024 bytes, which is the maximum memory that 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 () is what, just talked about if you run Java without adding-XMS parameters, then, in the Java program running process, memory is always slowly from the operating system to dig, basically is how much digging how much, But Java Virtual machine 100% in the case of a little bit more digging, these dug and no use of memory, is actually freememory (), so the value of freememory () is generally very small, However, if you are running Java programs using-XMS, this time because the program at startup will be unconditionally dug from the operating system-XMS the amount of memory defined later, this time, the memory dug up may be mostly useless, so this time freememory () may be some
--------------------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
By default, hotspot uses the replication collector in the new domain. This field is generally divided into three parts. The first part is Eden, which is used to generate new objects. The other two are called rescue spaces, and when Eden is full, the collector stops the application, copies all reachable objects to the current from rescue space, and once the current from rescue space is filled, the collector copies the reachable objects to the current to rescue space. From and to rescue space swap roles. The active objects will continue to replicate in the rescue space until they have been used and transferred to the old domain. Use-xx:survivorratio to control the size of new domain sub-spaces.
As with Newration, Survivorration prescribes the ratio of a rescue area to Eden space. For example, the following command sets the new domain to 64m,eden of 32m, each of which occupies 16m:
Java-xms256m-xmx256m-xmn64m-xx:survivorration =2
As mentioned earlier, the hotspot uses the replication collector for the new domain by default, and uses the tag-purge-compress collector for the old domain. Using the replication collector in a new domain has a lot of meaning, because most of the objects that the application generates are short-lived. Ideally, all transition objects will be collected when they are moved out of Eden Space. If this is the case, and the objects that move out of the Eden space are long-lived, you can theoretically move them into the old domain immediately, avoiding repeated duplication in the rescue space. However, applications do not fit into this ideal state because they have a small percentage of objects that are long-lived. It is best to keep these long-lived objects in the new domain, because copying a small portion of the object is always cheaper than compressing the old domain. To control the replication of objects in the new domain, you can use-xx:targetsurvivorratio to control the proportions of the rescue space (the value is the usage ratio for setting up the rescue space. If the salvage space is 1M, the value 50 indicates available 500K). The value is a percentage, and the default value is 50. When the larger stack uses a lower sruvivorratio, the value should be increased to 80 to 90 to make better use of the rescue space. The upper limit can be controlled with-xx:maxtenuring threshold.
The maxtenuring threshold can be set to 0 to place all replication occurrences and to extend the object from Eden to the old domain. After the setup is complete, the rescue space is not actually used, so the survivorratio should be set to the maximum to maximize Eden space, set as follows:
Java ...-xx:maxtenuringthreshold=0–xx:survivorratio=50000 ...
Garbage Collection Description:
Garbage collection sub-level, Level 0 for all (full) garbage collection, will reclaim the old section of garbage, Level 1 or above is a partial garbage collection, will only recover the garbage in young, memory overflow usually occurs after the old or perm segment garbage collection, still no memory space to accommodate the new Java objects.
When a URL is accessed, the memory application process is as follows:
A. JVM tries to initialize a chunk of memory in Eden for related Java objects
B. When the Eden space is sufficient, the memory request ends. Otherwise to the next
C. The JVM attempts to release all inactive objects in Eden (this is a garbage collection of 1 or more advanced); If Eden space is still insufficient to fit into the new object after release, an attempt is made to put some of the active objects in Eden into the Survivor area/old area
D. The survivor area is used as an intermediate swap area for Eden and old, and when the old area is sufficiently large, the objects in the Survivor area will be moved to the old area, otherwise they will remain in the survivor area.
E. When there is not enough space in the old area, the JVM performs a full garbage collection in the old area (level 0)
F. After a complete garbage collection, "Out of memory error" occurs if the survivor and old areas still cannot hold portions of objects copied from Eden, causing the JVM to be unable to create an area for the new object in the Eden area
Java Heap Related parameters:
MS/MX: Defines the total size of the Young+old segment, MS is the memory size Young+old when the JVM starts, and MX is the maximum amount of young+old 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.
Newsize/maxnewsize: Defines the size of the young segment, NewSize the memory size of young when the JVM starts, and maxnewsize is the maximum amount of young 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.
Permsize/maxpermsize: Defines the size of the perm segment, permsize the memory size perm 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.
Survivorratio: Setting the proportions of the survivor Space and Eden space
Cases:
Mem_args= "-XMS512M-XMX512M-XX:NEWSIZE=256M-XX:MAXNEWSIZE=256M-XX:PERMSIZE=128M-XX:MAXPERMSIZE=128M-XX: Survivorratio=6 "
In the example above:
young+old:512m
young:256m
perm:128m
eden:young*6/(6+1+1) =192m
survivor:young/(6+1+1) =32m
Total size of Java heap =young+old+perm=640m
This document comes to: http://itindex.net/detail/54642-tomcat-very-likely?utm_source=tuicool&utm_medium=referral
Tomcat error: This was very likely to create a memory leak problem resolution