Tomcat启动时项目重复加载,导致资源初始化两次!
一、现象:
每次启动Tomcat 的时候,工程会被加载两次配置虚拟目录引起,如下配置:
<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="d:\myapp"/>
</Host>
<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="d:\myapp"/> </Host>
<Host name="localhost" debug="0" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Context path="" docBase="d:\myapp"/> </Host>
前提:服务器经常出现崩溃,出现Memory leak 错误,想要找一下原因
常见的Java内存溢出有以下三种:
1、java.lang.OutOfMemoryError: Java heap space ----JVM Heap 堆溢出
JVM在启动的时候会自动设置JVM Heap的值,其初始空间(即-Xms)是物理内存的1/64,最大空间(-Xmx)不可超过物理内存。
可以利用JVM提供的-Xmn -Xms -Xmx等选项可进行设置。Heap的大小是Young Generation 和Tenured Generaion 之和。
在JVM中如果98%的时间是用于GC,且可用的Heap size 不足2%的时候将抛出此异常信息。
解决方法:手动设置JVM Heap 堆的大小。
linux下的tomcat:
修改TOMCAT_HOME/bin/catalina.sh
在“echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
JAVA_OPTS="-server -Xms256m -Xmx512m "
-server:一定要作为第一个参数,在多个CPU时性能佳
-Xms:java Heap初始大小。 默认是物理内存的1/64。
-Xmx:java heap最大值。建议均设为物理内存的一半。不可超过物理内存。
2、 java.lang.OutOfMemoryError: PermGen space ---- PermGen space溢出。
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。
为什么会内存溢出,这是由于这块内存主要是被JVM存放Class和Meta信息的,Class在被Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,GC不会在主程序运行期对PermGen space进行清理,所以如果你的APP会载入很多CLASS的话,就很可能出现PermGen space溢出。
解决方法: 手动设置MaxPermSize大小
JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m"
-XX:PermSize:设定内存的永久保存区初始大小,缺省值为64M。
-XX:MaxPermSize:设定内存的永久保存区最大 大小,缺省值为64M。
-XX:NewSize: 新生成的池的初始大小。 缺省值为2M。
-XX:MaxNewSize: 新生成的池的最大大小。 缺省值为32M。
如果 JVM 的堆大小大于 1GB,则应该使用值:-XX:newSize=640m -XX:MaxNewSize=640m -XX:SurvivorRatio=16,或者将堆的总大小的 50% 到 60% 分配给新生成的池。调大新对象区,减少Full GC次数。
JAVA_OPTS=-Xms64m -Xmx256m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m。
3、 java.lang.StackOverflowError ---- 栈溢出
栈溢出了,JVM依然是采用栈式的虚拟机。函数的调用过程都体现在堆栈和退栈上了。
调用构造函数的"层"太多了,以致于把栈区溢出了。
通常来讲,一般栈区远远小于堆区的,因为函数调用过程往往不会多于上千层,而即便每个函数调用需要 1K的空间,那么栈区也不过是需要1MB的空间。通常栈的大小是1-2MB的。
通常递归也不要递归的层次过多,很容易溢出。
解决方法:修改程序。
http://lanxing.iteye.com/blog/1056561
最后贴上官方文档上对tomcat的三种Connector的方式做一个简单比较,
Java Blocking Connector Java Nio Blocking Connector APR Connector
Classname Http11Protocol Http11NioProtocol Http11AprProtocol
Tomcat Version 3.x 4.x 5.x 6.x 6.x 5.5.x 6.x
Support Polling NO YES YES
Polling Size N/A Unlimited - Restricted by mem Unlimited
Read HTTP Request Blocking Blocking Blocking
Read HTTP Body Blocking Blocking Blocking
Write HTTP Response Blocking Blocking Blocking
SSL Support Java SSL Java SSL OpenSSL
SSL Handshake Blocking Non blocking Blocking
Max Connections maxThreads See polling size See polling size