关于中间件内存(缓存)溢出的情况分析及解决办法

因为系统运行时间过程中,weblogic内存中积累了过量的垃圾文件,导致jta资源不足、jdbc找不到连接资源,最后系统崩溃,无法运行。

后台会有如下显示:

类似于这样的错误,可以通过修改C:\\bea\\weblogic81\\common\\bin\\commEnv.cmd 这个脚本文件。修改内容如下:

goto continue :bea

if \set JAVA_VM=-jrockit

set MEM_ARGS=-Xms128m -Xmx512m

set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none goto continue

:bea_prod_mode

set JAVA_VM=-jrockit

set MEM_ARGS=-Xms256m -Xmx512m goto continue 修改为: goto continue :bea

if \set JAVA_VM=-jrockit

set MEM_ARGS=-Xms768m -Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC

set JAVA_OPTIONS=%JAVA_OPTIONS% -Xverify:none goto continue :bea_prod_mode

set JAVA_VM=-jrockit

set MEM_ARGS=-Xms768m -Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC

goto continue

WebLogic用了一段时间之后,偶尔总是会出现OutOfMemory,这对测试环境来说,还只要Restart Server 就可以解决,但是在正式环境上出现可就麻烦大了,因为一Restart Server 所有User就都无法使用系统,所以MEM_ARGS这个参数的设定就很重要。

这是SIT目前的设定,依不同的系统做不同的设定

MEM_ARGS=\-Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC\

提示:以上记得要写成一行。

Heap Size设定

-Xms 设定一开始的Heap Size。

-Xmx 设定Heap Size的最大值 (最好是不是超过物理内存的80%)。 -XX:NewSize 调整JVM的Young Generation的size大小。

-XX:MaxNewSize 调整JVM的Young Generation的size的最大值。

– Xmn Young Generation的size,NewSize 和 MaxNewSize设定为一样。 -XX:NewRatio 控制Young generation的比例,如-XX:NewRatio=3表示Young generation与Old generation的比例为1:3,即Young generation占1/4,Old generation占3/4。

Young generation又被分成三部分,第一部分Eden,用于生成新的Object。另外两个部分为Survivor空间,当Eden用完后,会将 Objects复制到\,当SS1空间满了的时候,再被复制到\,Objects会在Survivor空间不断的被复制,直到他满足条件进入Old generation止。

提示:如果将Heap Size设的越大,GC的周期就会拉长,而且每次GC的时间也会越长。

PermGen space

-XX:PermSize 这一部分是用于存放Class和Meta的讯息,Class在被 Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期间对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。

整个内存配置会像这样

-XX:+DisableExplicitGC 加了这个参数会停止掉WLS或是程序内直接呼叫GC,减少不必要的GC,将GC交由JVM去执行。

Garbage Collection描述:

Garbage Collection分多种等级,0级就是全部的垃圾回收(Full GC),会回收Old generation中的垃圾;1级或以上为部分垃圾回收,只会回收Young中的垃圾,会发生OutOfMemory通常是产生于Old generation或Perm段垃圾回收后,仍然没有内存空间来存放新的Java 对象的情况。

当一个URL被访问时,内存的配置过程如下:

  1. JVM会试图为Java的相关对象在Eden中初始化一块内存空间 B. 当Eden空间足够时,内存配置结束。否则到下一步
  2. JVM会试图释放在Eden中所有不活跃的对象(这是属于1或更高级的垃圾回收);释放后若Eden空间仍然不足以放入新对象,则会试图将部分Eden中活跃的对象放入Survivor区/OLD区
  3. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够,Survivor区的对象会被移到Old区,否则被保留在Survivor区
  4. 当OLD区空间不足时,JVM会在OLD区进行完全的垃圾收集(0级) F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,就会导致JVM无法在Eden区为新的对象配置出内存区块,产生\的错误\

以我的设定为例:

MEM_ARGS=\-Xmx768m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:MaxPermSize=384m -XX:PermSize=384m -XX:SurvivorRatio=6 -XX:+DisableExplicitGC\

在上面的例子中: YOUNG+OLD: 768M YOUNG: 256M Perm: 384M

Eden: YOUNG*6/(6+1+1)=192M Survivor: YOUNG*1/(6+1+1)=32M Heap Size: YOUNG+OLD+Perm=1024M

以上是WebLogic内存参数的一些基本的设定,太难的我也不会,只是整理一些心得而己,提供做一下参考

堆( Heap)是 Java 程序的对象生活的地方,包含活的对象,死的对象以及剩余内存 。 当对象不能被运行中的程序的指针所到达时,这些对象成为”垃圾“。 JVM 的堆大小决定了 VM 花费在收集垃圾上的时间和频度。 收集垃圾可以接受的速度与应用有关,应该通过分析实际的垃圾收集的时间和频率来调整。

如果堆的大小很大,那么完全垃圾收集就会很慢,但是频度会降低。

如果你把堆的大小和内存的需要一致,完全收集就很快,但是会更加频繁。 调整堆大小的的目的是最小化垃圾收集的时间,以在特定的时间内最大化处理客户

的请求。

在基准测试的时候,为保证最好的性能,要把堆的大小设大,保证垃圾收集不在整个基准测试的过程中出现。

堆划分为两个区域:新生代和旧生代。

新生代又分为:Eden 和两片生存空间(survivor spaces)。其中保证有一片空间在任何时间是空的,当垃圾收集发生时, Eden 中的活的对象复制到下一片生存空间,对象就在生存空间之间复制,直到到达最大门限值(老化),然后复制到旧生代。

Eden 是新的对象分配的地方。

很多对象分配以后很快成为垃圾,这些对象称为具有 \ 对象生存的时间越长,需要的收集时间也越长,因此,收集变慢。

你的应用建立和释放对象的速度决定了垃圾收集的频度。因此,在编程时,应注意使用对象的缓冲,而不是新建立对象。

大多数对象在新生代就已经死去,因此你能有效的调整垃圾收集。如果你能安排大多数对象的生存期小于一个收集时间,那么,垃圾收集是十分高效的。

错误的”代“配置会导致频繁的垃圾收集,影响系统性能。 如果系统花费很多的时间收集垃圾,请减小堆大小。 一次完全的垃圾收集应该不超过 3-5 秒。

一般说来,你应该使用物理内存的 80% 作为堆大小。 在最大工作负荷的时候,监视 WebLogic 的性能。

使用 -verbosegc 选项测量有多少时间和资源用于垃圾收集。 打开垃圾收集的详细信息输出以及复位向:

% java -ms64m -mx64m -verbosegc -classpath $CLASSPATH -Dweblogic.domain=mydomain -Dweblogic.Name=clusterServer1 -Djava.security.policy==/bea/weblogic6x/lib/weblogic.policy -Dweblogic.management.server=192.168.0.101:7001 -Dweblogic.management.username=system

-Dweblogic.management.password=systemPassword weblogic.Server >> logfile.txt 在 Solaris 系统上,采用下面的命令: weblogic.Server > server.out 2>&1 Java HotSpot VM 选项

标准的选项在各种平台都已经有介绍:

http://java.sun.com/j2se/1.3/docs/tooldocs/win32/java.html http://java.sun.com/j2se/1.3/docs/tooldocs/solaris/java.html http://java.sun.com/j2se/1.3/docs/tooldocs/linux/java.html

以 -X 开头的选项都为非标准选项(并不能在所有的 VM 上实现),在后续的版本中可能会不通知而变更。

由于 -XX 选项需要特别的系统权限,因此不建议随便使用。

在 1.3.0 之前的版本, J2SDK 的 Solaris 版本带有一个虚拟机的实现叫做 Exact VM(EVM),从 1.3.0 开始这个虚拟机被 Java HotSpot VM 所取代。

Java HotSpot VM 目前认识下面的 -X 选项: -Xincgc 使用训练 GC

-Xnoincgc 不是用训练 GC(缺省)

-XX:MaxHeapFreeRatio= 最大堆剩余百分比(缺省 70) -X:MinHeapFreeRation= 堆最小剩余百分比(缺省 40)

-Xint 只作解析 (不作 JIT 编译)

-XX:+UseBoundThreads 绑定用户级别的线程 (只针对 Solaris)

-Xmn 设置年轻一代的大小( young generation )(只对 1.4)

对象分配在 Eden,并且在这里死亡,当 Eden 满时,引起一个小的收集(minor collection),一些生存的对象被移动到旧生代,如果旧生代需要收集,则引起大收集(major collection ),这会比较缓慢。

如果 GC 成为瓶颈,那么需要指定代的大小,检查 GC 的详细输出,研究 GC 参数对性能的影响。

旧生代的收集采用 mark-compact 的方式,其中的一部分叫做”永久代“(permanent generation)很特别,他包括了 JVM 自身的所有反映数据(reflective data),例如类以及方法。

暂停时间的含义是应用因为垃圾收集而显示出来的短暂停顿。 吞吐量的含义是在一段比较长的时间内,没有用在垃圾收集的时间和总时间的百分比。

减少暂停时间的办法可以采用小的年轻代和增量收集,但是这以牺牲吞吐率为代价。

Footprint 是一批工作进程的集合,以页和缓冲行数计量,在物理内存有限或者有很多处理器的系统里,footprint 可代表伸缩性。

Promptness 是对象死去的时间和内存变为可用时的时间差,在分布系统中(包括 RMI)需要考虑。

很大的新生代能提高吞吐率,但是牺牲了 footprint 和 promptness。 Solaris 的 footprint 可以采用 pmap 命令来查看。 [GC 325407K->83000K(776768K), 0.2300771 secs] [GC 325816K->83372K(776768K), 0.2454258 secs] [Full GC 267628K->83769K(776768K), 1.8479984 secs]

上面的三行是 GC 的详细输出,我们可以看到两次小收集和一次大收集。箭头前后的两个数字代表 GC 后活的对象的组合长度。括号内的数字代表合计的空间,等于堆大小减去一片生存空间。

除非你遇到暂停的问题,否则,可以分配足够的内存给 JVM,缺省的 64MB 总是太小。

设置 -Xms 和 -Xmx 为同样的值能提高 JVM 的预测,但是如果你的选择不对的话, JVM 不会补偿。

当增加处理器时,记得增加内存,因为分配可以并行进行,而 GC 不是并行的。 NewSize 和 MaxNewSize 绑定新生代的长度的低端和高端,设置为一样大小时和 -Xms 和 -Xmx 一样解决新生代的预测时间。

如果生存空间太小,拷贝直接进入旧生代,如果太大的话,会空闲在那里。

除非你碰到过渡的大收集或者暂停时间,否则分配足够的内存给新生代,缺省的 MaxNewSize (32MB) 往往太小。

如果需要的话,最大的永久代大小可以使用 MaxPermSize 增加。 直接的 GC 调用可以采用 -XX:+DisableExplicitGC 来关闭。

对于大服务器 而言,1.4 的 JVM 能提供 64 bit 寻址能力,提供更大的新生代大小,并发收集来减少大收集引起的暂停的影响。

Java HotSpot Client VM 主要用于减少应用启动时间以及内存的 footprint 。

Java HotSpot Server VM 和 Java HotSpot Client VM 类似,但是在最大性能上作了

调整。用于长期运行的服务应用。

Solaris 和 Linux 的 J2SE 1.3 随带 Java HotSpot Server VM 预安装。

以下文章点击率最高

Loading…

发表评论