2011年10月13日
摘要: 页面表单:Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><!DOCTYPE html><html lang="en"><head> <meta...
阅读全文
资源pom.xml
<properties>
<slf4j.version>1.7.1</slf4j.version>
<log4j.version>1.2.17</log4j.version>
<logback.version>1.0.1</logback.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- logging related -->
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- common-logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<!-- java.util.logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<!-- slf4j-log4j绑定 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>runtime</scope>
<version>${logback.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>${logback.version}</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
a.slf4j/logback 组合(logback.xml)
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
b.slf4j/log4j组合(log4j.properties or log4j.xml)
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<!-- slf4j-log4j绑定 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
c.如果是已用了commons-logging/log4j想用用slf4j/logback,那也容易用下面的配置
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- common-logging 实际调用slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<!-- log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
再到http://logback.qos.ch/translator/Welcome.do,將你原來的log4j.properties转成logback.xml
就可以將commons-logging.jar 跟 log4j.jar自你系統中移除了
环 境 a.下载 BeanSoft的绿色版mysql
(Copy 成两份 ,master,slave) 取mysql\mysql50green下内容复制
b.
在cmd命令行模式下进入master
\bin 执行mysqld install
master命令。作用是为Mysql安装一个服务,服务名是
master 。同理操作slave 。(注意
mysqld =mysqld-nt
)c.
在运行里运行REGEDIT,打开WINDOWS注册表编辑器,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\master 打开,修改下面的ImagePath数值: "X:\
master \bin\mysqld" --defaults-file="D:\master\my.ini"
master 确定,退出注册表编辑器。 (同理操作slave)
d.定义my.ini拷贝到 X
:\ master 下面
[client]
port = 3308
[mysqld]
port =3308
server-id = 1
binlog-do-db=test1 ##要同步的数据库名为test1
log-bin =mysql-bin
e.定义my.ini拷贝到x:\slave下面
[client]
port = 3309
[mysqld]
port = 3309
server-id = 2
master-host = 127.0.0.1
master-user = slaver1
master-password = slaver1pwd
master-port = 3308
replicate-do-db=test1 ##要同步的数据库
f. 然后在master
Console 执行: GRANT FILE,SELECT,REPLICATION SLAVE ON *.* TO 'slaver1'@'127.0.0.1' IDENTIFIED BY 'slaver1pwd';
开一个新账号(用户名:slaver1 密码:slaver1pwd)并赋于权限
运行Mysqld.exe,并创建新数据库test1,可在Console下输入:show master status\G查看状态!
*************************** 1. row*****************
File: mysql-bin.000305
Position: 98
Binlog_Do_DB: test1
Binlog_Ignore_DB:
g.
运行Slaver 的Mysqld.exe,在Console窗口执行 show slave status\G 查看状态,如下:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 127.0.0.1
Master_User: slaver1
Master_Port: 3308
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 2495
Relay_Log_File: 2012-0416-1022-relay-bin.000007
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: test1
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 2495
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
1 ::Windows XP配置
2 set pan=%0
3 set pan=%pan:~1,3%
4 set devenvdir=%pan%DEV_FOR_JEE
5
6 ::windows 7手动输入盘符,放开注释
7 set devenvdir=X:\DEV_FOR_JEE
8
9 wmic ENVIRONMENT where "name='JAVA_HOME'" delete
10 wmic ENVIRONMENT where "name='MVN_HOME'" delete
11 wmic ENVIRONMENT where "name='ClassPath'" delete
12 wmic ENVIRONMENT where "name='M2_REPO'" delete
13 wmic ENVIRONMENT create name="JAVA_HOME",username="<system>",VariableValue="%devenvdir%\java1.6"
14 wmic ENVIRONMENT create name="MVN_HOME",username="<system>",VariableValue="%devenvdir%\maven3.0.4"
15 wmic ENVIRONMENT create name="M2_REPO",username="<system>",VariableValue="%devenvdir%\repository"
16 wmic ENVIRONMENT create name="ClassPath",username="<system>",VariableValue="%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\bin;.;"
17 wmic ENVIRONMENT where "name='Path' and username='<system>'" set VariableValue="%%JAVA_HOME%%\bin;%%MVN_HOME%%\bin;%%M2_REPO%%;%path%"
18 pause
19
这里根据平时遇到的情况和相关资料进行一个总结。常见的一般会有下面三种情况:
1.OutOfMemoryError: Java heap space
2.OutOfMemoryError: PermGen space
3.OutOfMemoryError: unable to create new native thread.
对于前两种情况,在应用本身没有内存泄露的情况下可以用设置tomcat jvm参数来解决。(-Xms -Xmx -XX:PermSize -XX:MaxPermSize)
最后一种可能需要调整操作系统和tomcat jvm参数同时调整才能达到目的。
第一种:是堆溢出。
在JVM中如果98%的时间是用于GC且可用的 Heap size 不足2%的时候将抛出此异常信息。
没有内存泄露的情况下,调整-Xms -Xmx参数可以解决。
-Xms:初始堆大小
-Xmx:最大堆大小
但堆的大小受下面三方面影响:
1.相关操作系统的数据模型(32-bt还是64-bit)限制;(32位系统下,一般限制在1.5G~2G;我在2003 server 系统下(物理内存:4G和6G,jdk:1.6)测试 1612M,64为操作系统对内存无限制。)
2.系统的可用虚拟内存限制;
3.系统的可用物理内存限制。
堆的大小可以使用 java -Xmx***M version 命令来测试。支持的话会出现jdk的版本号,不支持会报错。
-Xms -Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m
第二种:永久保存区域溢出
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。但目前的hibernate和spring项目中也很容易出现这样的问题。http://www.javaeye.com/topic/80620?page=1 的帖子有讨论的这个问题。可能是由于这些框架会动态class,而且jvm的gc是不会清理PemGen space的,导致内存溢出。
这一个一般是加大-XX:PermSize -XX:MaxPermSize 来解决问题。
-XX:PermSize 永久保存区域初始大小
-XX:PermSize 永久保存区域初始最大值
这一般结合第一条使用,比如 set JAVA_OPTS= -Xms1024m -Xmx1024m -XX:PermSize=128M -XX:PermSize=256M
有一点需要注意:java -Xmx***M version 命令来测试的最大堆内存是 -Xmx与 -XX:PermSize的 和 比如系统支持最大的jvm堆大小事1.5G,那 -Xmx1024m -XX:PermSize=768M 是无法运行的。
第三种:无法创建新的线程。
这种现象比较少见,也比较奇怪,主要是和jvm与系统内存的比例有关。
这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G),并且它至少要占用可用内存的一半。有人发现,在线程个数很多的情况下,你分配给JVM的内存越多,那么,上述错误发生的可能性就越大。
产生这种现象的原因如下(从这个blog中了解到原因:http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html):
每一个32位的进程最多可以使用2G的可用内存,因为另外2G被操作系统保留。这里假设使用1.5G给JVM,那么还余下500M可用内存。这500M内 存中的一部分必须用于系统dll的加载,那么真正剩下的也许只有400M,现在关键的地方出现了:当你使用Java创建一个线程,在JVM的内存里也会创 建一个Thread对象,但是同时也会在操作系统里创建一个真正的物理线程(参考JVM规范),操作系统会在余下的400兆内存里创建这个物理线程,而不 是在JVM的1500M的内存堆里创建。在jdk1.4里头,默认的栈大小是256KB,但是在jdk1.5里头,默认的栈大小为1M每线程,因此,在余 下400M的可用内存里边我们最多也只能创建400个可用线程。
这样结论就出来了,要想创建更多的线程,你必须减少分配给JVM的最大内存。还有一种做法是让JVM宿主在你的JNI代码里边。
给出一个有关能够创建线程的最大个数的估算公式:
(MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads
对于jdk1.5而言,假设操作系统保留120M内存:
1.5GB JVM: (2GB-1.5Gb-120MB)/(1MB) = ~380 threads
1.0GB JVM: (2GB-1.0Gb-120MB)/(1MB) = ~880 threads
在2000/XP/2003的boot.ini里头有一个启动选项,好像是:/PAE /3G ,可以让用户进程最大内存扩充至3G,这时操作系统只能占用最多1G的虚存。那样应该可以让JVM创建更多的线程。
因此这种情况需要结合操作系统进行相关调整。
因此:我们需要结合不同情况对tomcat内存分配进行不同的诊断才能从根本上解决问题。
参考资料(从这些资料中受益良多):
http://www.javaeye.com/topic/80620?page=1
http://ggmm.blog.sohu.com/117545379.html
http://hi.baidu.com/hexiong/blog/item/16dc9e518fb10c2542a75b3c.html
http://www.wujianrong.com/archives/2006/12/javalangoutofmemoryerror_permg.html
from:http://www.blogjava.net/george/archive/2009/08/18/291579.html