`
huangxx
  • 浏览: 315481 次
  • 来自: ...
社区版块
存档分类
最新评论

Weblogic系统管理总结(7.1/8.0) - zt

阅读更多

https://dream4ever.org/showpost.php?p=756030&postcount=1

 

Weblogic系统管理总结(7.1/8.0)

关于JVM内存管理(适用于所有J2EE产品)
援引JDK1.3为例(JDK 1.4除了在垃圾回收上有变化,其他的变化不大):

现在无论是JDK1.3还是1.4,我们都是使用Sun JDK。
请注意:weblogic8.0自带了2种JDK,一种是Sun JDK,另一种是BEA自己的JRocket。

1. JVM内存段分配及启动参数:

J2EE服务器的内存组成:
? Java堆:我们的程序和对象都在这个堆进行管理
? C堆:当引用到一些Native的对象,如网络访问、OCI方式的数据库连接等都在C堆里进行管理

Java堆的描述:

如下图


? Young及Old区域用来存放由Java类而生成的内存对象;
? Perm区域用来存放Java类及其他虚拟机自己的静态数据

垃圾回收描述:

垃圾回收分多级,0级为全部(Full)的垃圾回收,会回收OLD段中的垃圾;1级或以上为部分垃圾回收,只会回收Young中的垃圾,内存溢出通常发生于OLD段或Perm段垃圾回收后,仍然无内存空间容纳新的Java对象的情况。

当一个URL被访问时,内存申请过程如下:
A. JVM会试图为相关Java对象在Eden中初始化一块内存区域
B. 当Eden空间足够时,内存申请结束。否则到下一步
C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收);释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区/OLD区
D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”

Java堆相关参数:

ms/mx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

SurvivorRatio:设置Survivor空间和Eden空间的比例

例:
MEM_ARGS="-Xms512m -Xmx512m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=128m -XX:MaxPermSize=128m -XX:SurvivorRatio=6"

在上面的例子中:
YOUNG+OLD: 512M
YOUNG: 256M
Perm: 128M
Eden: YOUNG*6/(6+1+1)=192M
Survivor: YOUNG/(6+1+1)=32M

Java堆的总尺寸=YOUNG+OLD+Perm=640M

2. JVM内存分析工具

可以使用HPjmeter来进行分析,需要将JDK的GC日志打开(-verbose:gc),可定期用HPjmeter对GC日志进行分析,Demo工具可提供Java Heap内存变化图,以及垃圾回收图,这样就很容易分析内存溢出时是哪个段产生问题

3. 内存溢出的可能性

1. OLD段溢出

这种内存溢出是最常见的情况之一,产生的原因可能是:
1) 设置的内存参数过小(ms/mx, NewSize/MaxNewSize)
2) 程序问题
? 单个程序持续进行消耗内存的处理,如循环几千次的字符串处理,对字符串处理应建议使用StringBuffer。此时不会报内存溢出错,却会使系统持续垃圾收集,无法处理其它请求,相关问题程序可通过Thread Dump获取(见系统问题诊断一章)

? 单个程序所申请内存过大,有的程序会申请几十乃至几百兆内存,此时JVM也会因无法申请到资源而出现内存溢出,对此首先要找到相关功能,然后交予程序员修改,要找到相关程序,必须在Apache日志中寻找。

? 当Java对象使用完毕后,其所引用的对象却没有销毁,使得JVM认为他还是活跃的对象而不进行回收,这样累计占用了大量内存而无法释放。由于目前市面上还没有对系统影响小的内存分析工具,故此时只能和程序员一起定位。

2. Perm段溢出

通常由于Perm段装载了大量的Servlet类而导致溢出,目前的解决办法:
1) 将PermSize扩大,一般256M能够满足要求
2) 若别无选择,则只能将servlet的路径加到CLASSPATH中,但一般不建议这么处理

3. C Heap溢出

系统对C Heap没有限制,故C Heap发生问题时,Java进程所占内存会持续增长,直到占用所有可用系统内存。以下是一个案例,发生在INCOME:

假如项目的生产环境为HPUX,使用的数据库连接池为OCI模式,在应用服务器所安装的Oracle客户端版本为Oracle 9201

症状:Java进程所占内存不断增长,直到使用完系统所有内存而崩溃。

寻找问题方法:

对UNIX操作系统来说,Java Heap在进程的数据段、C Heap在进程的堆栈段,我们持续分析Java进程的数据段及堆栈段的增长情况(系统有相关的内存分析的系统调用),结果发现其堆栈段持续增长,说明问题不在Java相关的部分,而是在其它部分。

OCI的内存申请不属于JAVA范畴,故将其客户端升为Oracle 9203,问题解决。

数据库连接方式
我们常用的数据库连接方式:
Thin:
配置connection pool所使用的连接字符串如下:jdbcracle:thin:@172.16.*.*:****:****
Demo配置只需要使用到classes12.zip/jar以及nls_charset12.zip/jar两个文件, 配置时将其放到CLASSPATH即可。

OCI:
需要安装Oracle客户端,并在用户的.bash_profile(UNIX操作系统为.profile)中加入类似变量定义:
ORACLE_BASE=/usr/local/oracle
ORACLE_HOME=$ORACLE_BASE/product/8.1.7
ORACLE_SID=or8i
ORACLE_OWNER=oracle
ORACLE_TERM=386
LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH
ORACLE_NLS=$ORACLE_HOME/ocommon/nls/admin/data
NLS_LANG="simplified chinese_china.ZHS16CGB231280"

同时在$ORACLE_HOME/network/admin/tnsnames.ora中配置相关数据库连接
在启动文件中将classes12.zip/jar以及nls_charset12.zip/jar两个文件的访问路径放到CLASSPATH中

配置connection pool所使用到的连接串:
user=…
password=…
dll=ocijdbc8
server=…
protocol=oci8
安装时的注意要点
1. Weblogic安装注意点

1) Weblogic的日志应调整为“info”,以提供更多信息
2) Weblogic的线程数及Weblogic的connection pool数
? Weblogic线程数通常为:单CPU线程数为15,双CPU为20-25
? Weblogic 数据库连接数可设为线程数+5
? 注意:线程数与数据库连接数不是越大越好,设得过大容易导致系统挂死或低效率

2. Demo系统由以下几部分组成:

1) Demo自己开发的核心系统,放在mydomain/applications下面作为发布对象,其中的serverclasses目录需要加入CLASSPATH
2) Demo引用的第三方类,主要用作字符及报表处理,放在mydomain/life_lib中,需要将其中每个jar文件的路径都放在CLASSPATH中
3) Demo的配置文件:
? 以前包括config.properties等配置文件放置于mydomain下,即系统缺省目录下
? 现在配置文件基本都放置于一指定的目录中,目录名由java启动参数中的“-Dconfig.file.path”所指定
? 当相关参数改动时,需要仔细检查所有配置文件中的每一项。

系统缓慢问题诊断方法
除了前面所说的内存溢出问题,我们很多时候会遇到另一个问题,就是系统挂起或缓慢。遇到Demo问题时:


对Weblogic来说,可以直接通过Console来看每个线程在处理什么任务,对其它J2EE服务器,可通过“kill -3 pid”来看。

有以下几种可能:
1) 应用服务器负载轻,每个线程处理的任务不规律,或者没有访问特别频繁的URL

可能是整个数据库的效率低下所导致,或者数据库有锁产生,检查数据库连接池,非weblogic的服务器可查看”kill -3 pid”的结果中是否有大量的JDBC锁;若连接池的使用率很高或存在大量的JDBC锁,则直接查看数据库是否有严重的性能问题或是否存在大量的锁(非专业人士可通过OEM查看)。

2) 应用服务器负载轻,每个线程处理的任务很有规律性

可能是某些程序数据库访问效率低下所导致,检查数据库连接池,非weblogic的服务器可查看”kill -3 pid”的结果中是否有大量的JDBC锁;若连接池的使用率很高或存在大量的JDBC锁,则直接将相关URL提交PM或程序员解决。

3) 应用服务器负载较重
此种情况下,如果数据库连接池使用率高,则仍然重点查看数据库效率。

否则:通过”kill -3 pid” 来做thread dump(此时可能console已经访问不了或很慢),对thread dump中”default”相关队列的线程做汇总分析,找到存在问题的程序访问,Demo程序即是问题的源头,可能是处理字符串、影像、PDF等类型的程序。

<!----><!---->

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics