resin配置,关于内存

Service Temporarily Unavailable

The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

Apache/2.0.59 (Unix) Resin/3.1.12 Server at ad2.easou.com Port 80


可以尝试

解决方案 

1 这是因为用户站点使用的带宽超过了设定的最高限额引起的。 

为了不显示这个错误信息,可以在apache(Unix平台最流行的WEB服务器平台)的配置中加上一个配置,当超出带宽时,让访问变慢,而不是立即显示错误信息。 

编辑/usr/Prima(最完善的虚拟主机管理系统)/apache(Unix平台最流行的WEB服务器平台)_ssl/conf/httpd.conf,找到<IfModule mod_throttle.c>,在块中加入 

ThrottleMaxDelay 0 

重起apache(Unix平台最流行的WEB服务器平台): 

/etc/init.d/httpd restart 

还可以编辑一个显示服务器忙的html文件,放到/www/icons/busy.html,在httpd.conf中加入: 

ErrorDocument 503 /icons/busy.html 



出现OutOfMemoryException的解决方法
出现OOM异常大多数是因为分配给Resin的内存过小造成的,这个时候可以使用以下命令增大Resin的内存:

unix> bin/httpd.sh -Xmn100M -Xms500M -Xmx500M
win> bin/httpd.exe -Xmn100M -Xms500M -Xmx500M
install win service> bin/httpd.exe -Xmn100M -Xms500M -Xmx500M -install
这样就可以设置Resin使用的内存了

 

[开发]resin+spring+struts配搭在线上常见的三个问题

http://blog.chinaunix.net/uid-20787846-id-3471983.html

1、文件句柄数问题

现象1:访问页面出现500错误,错误描述为:java.lang.NoClassDefFoundError,后面跟的类名各式各样不一一列举了。

现象2:Resin被Wathcdog自动重启,日志中表明这是因为:Resin shutdown from out of file descriptors

分析:由于Linux默认文件句柄限制为1024(通过命令ulimit –n来查看),所以当Web Server应对高负载起了大量线程,incoming socket connections和outgoing socket connections都很多,而且后台代码也可能涉及大量句柄打开,尤其是struts+spring组合。

因此当句柄数迅速到达1024的限制后,无法打开新句柄,于是乎文件打不开、类定义找不到,诸如此类的错误就出现了。

解决:

短期策略是调大Linux下对文件句柄数限制。操作如附录1所示。对于这个数字,一般建议是32667,也可以设置的更大,我们直接调为51200。

 

2、PermSize问题

现象:Resin被持续访问一段时间后,比如一天,就会报告如下500错误,导致所有页面不能访问:

OutOfMemoryError:PermGen space

此时,就只能重启机器了,重启resin都没用。

分析:因为线上用了spring+struts,这些框架用到大量动态class,ClassLoader是把这部分内存放在PermGen space里的。而JVM的GC是不会清理PermGen space的。这样很容易导致线上应用报告PermGen space内存溢出。

解决:通过在resin.xml中增加jvm-arg一系列参数,调大“PermSize”和“MaxPermSize”这两个参数来尽量避免出现JVM内存永久保存区域溢出错误。PermSize默认值参考附录2。修改情况参见附录3。

 

3、Xmx和Xms问题

现象:Resin报告如下500错误,导致所有页面不能访问:

OutOfMemoryError:Java heap space

此时重启resin还可以恢复。

分析:JVM默认的最大可用内存(-Xmx参数)和初始堆大小(-Xms参数)都偏小,很容易限制住服务器的能力。当Java架构的能力还没有发挥出来时,就已经被系统默认的各种参数限制住了,导致各种各样的异常。

解决:通过在resin.xml中增加jvm-arg一系列参数,调大“Xms”和“Xmx”以及“Xmn”这三个参数。修改情况参见附录3。Xmn附录4。

其中Xmx的值可以设置得很大,比如4096MB,跟你的物理内存大小差不太多都行,64位Linux支持得住。Xmn的值是Xmx数值的1/4。

Xms的值可以与Xmx一样,省得当压力上来后,初始堆大小发现不够,JVM又得花时间去把内存区大小扩到最大可用内存的数值,就在这个过程,持续不断的高负载可能已经将服务器冲垮。这个机理就类似于我们熟知的SQL Server要根据业务,仔细思考指定数据库空间初始值和最大值以及自增长模式。默认SQL Server数据库空间自动增长是按10%比例增加的:如果你最开始建库时分配了1GB空间,但当压力上来后,数据很快到达1GB,那么数据库就会先锁住所有请求,自动在磁盘上增长出100MB的空间,在这个自动增长过程,所有Web请求就会被挂住,最终可能全部超时。

 

附录附录1:

编辑/etc/profile,加入

ulimit -n 51200

有人认为设置为4096就可以,但在网络服务器上此数字最好调成几万,不然流量冲上来太容易冲破。

还有设置命令是:ulimit?–SHn 51200,-S、-H这两个参数的说明如下:

-H 设置硬件资源限制。
-S 设置软件资源限制。
-n size:设置内核可以同时打开的文件描述符的最大值。

还有另一种操作修改三个地方的设置,参见《修改 Ubuntu ulimit 限制》。

 

附录2:

没有给resin.xml加PermSize的情况下,默认计算规则是:

“JVM使用-XX:PermSize设置非堆内存初始值,默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小,默认是物理内存的1/4。”

那么,如果是物理内存4GB,那么64分之一就是64MB,这就是PermSize默认值,也就是永生代内存初始大小;

四分之一是1024MB,这就是MaxPermSize默认大小。

 

附录3:

优化规则:Server端的JVM最好将-Xms和-Xmx设为相同值。为了优化GC,最好让-Xmn值约等于-Xmx的1/4。

线上resin 4.0.15的resin.xml中增加如下配置节点:

<server-default>

    <jvm-arg>-Xms4096m</jvm-arg>

    <jvm-arg>-Xmx4096m</jvm-arg>

    <jvm-arg>-Xmn1024m</jvm-arg>

    <jvm-arg>-XX:PermSize=128m</jvm-arg>

    <jvm-arg>-XX:MaxPermSize=256m</jvm-arg>

    <thread-max>1024</thread-max>

    <socket-timeout>30s</socket-timeout>

    <keepalive-max>512</keepalive-max>

    <keepalive-timeout>60s</keepalive-timeout>

</server-default>

 

附录4:

JVM的-Xmn参数含义是Young Generation的heap size。

JVM有2个GC线程。第一个线程负责回收Heap的Young区。第二个线程在Heap不足时,遍历Heap,将Young 区升级为Older区。Older区的大小等于-Xmx减去-Xmn,不能将-Xms的值设的过大,因为第二个线程被迫运行会降低JVM的性能。

 

resin的JVM參數調整

http://www.360doc.com/content/13/0827/11/13653527_310196338.shtml

<!-- - JVM 参数设置 -->
<jvm-arg>-Xms 512 m</jvm-arg>
( jvm 最小内存,也是启动 resin后的默认内存分配值)
<jvm-arg>-Xmx 512 m</jvm-arg> <!-- make ms=mx to reduce GC times -->
( jvm最大内存,当内存使用超过 Xms分配的值之后会自动向这个最大值提升,一般配置成最大最小值相等,理论上能够降低 GC 垃圾收集的时间,可按实际进行配置)
<jvm-arg>-Xmn 86 m</jvm-arg>

(内存分配增量,当内存需求超过 Xms值之后进行第一次分配请求的内存值,一般为 Xmx的 1/3-1/4 ;开始时候可以先屏蔽,当应用出现OutOfMemory的时候再打开也可以)

<jvm-arg>-XX:MaxNewSize= 256 m</jvm-arg>
<jvm-arg>-XX:PermSize= 128 m</jvm-arg>
<jvm-arg>-XX:MaxPermSize= 256 m</jvm-arg>
(以上三项是为了减少 OutOfMemory 而配置的,是每个 java编译执行的时候最多能一次申请 jvm 内存空间的值,以上默认配置基本够用,但依然出OutOfMemory 的时候可以适当调大,但不能超越 Xmx的值;开始时候可以先屏蔽,当应用出现 OutOfMemory的时候再打开也可以)
<jvm-arg>-Xss256k</jvm-arg> <!-- jvm Stack config -->
<jvm-arg>-Djava.awt.headless=true</jvm-arg> < (允许使用验证码)
<jvm-arg>-Djava.net.preferIPv4Stack=true</jvm-arg> <!-- disable IPv6 -->
<jvm-arg>-Doracle.jdbc.V8Compatible=true</jvm-arg>(针对 oracle10的兼容配置)
<watchdog-arg>-Dcom.sun.management.jmxremote</watchdog-arg>


<!-- 强制 resin 强制重起时的最小空闲内存 -->
<memory-free-min> 2 M</memory-free-min>


<!-- 最大线程数量 . -->
<thread-max>256</thread-max>


<!-- 套接字等待时间 -->
<socket-timeout>65s</socket-timeout>


<!-- 配置 keepalive -->
<keepalive-max>128</keepalive-max>
<keepalive-timeout>15s</keepalive-timeout>

Resin 中 JVM 的分析
JVM 虚拟内存

JVM 虚拟内存与系统内存的关系图:

834950_201112271005410038.jpg

-Xms 初始化 jvm 的时候从系统内存划分的 heap 内存数量
-Xmx jvm 最大能使用的 heap 内存数量
-Xmn ( -XX:NewSize/ -XX:MaxNewSize )年轻代占 heap 的内存数量
-XX:PermSize / -XX:MaxPermSize 持久代占用的系统内存数量
-Xss 单 个线程 堆栈 占的内存量,跟线程数相关
整个 JVM 的工作流程是:新的线程在 Eden 生成; Eden 满,把有经常访问的资
源放在 SO1 中,对 Eden 进行空间回收;当 SO1 满,将常使用的资源放到 SO2 ,对 SO 1
的空间进行回收;当 SO2 满,将经常访问的资源放到 Old ,对 SO2 进行空间回收;
按一定的规则对 Old 的资源进行处理。(为了容易记忆,我们可以对 SO1 、 SO2 、 O ld
起个其他的名字,分别是 幸存者 1 区,幸存者 2 区和养老区 )
简单概括为: Heap 设定与垃圾回收 Java Heap 分为 3 个区, New , Old 和
Permanent 。 New 保存刚实例化的对象。当该区被填满时, GC 会将对象移到 Old 区 。
Permanent 区则负责保存反射对象。 ( Perm 区在过去持久化没有使用的年代默认 的
配置已经足够使用,但现在要注意该区的情况,有可能 OOM--out of menery 就
是由于它而发生)
从上面的 JVM 工作机制,我们可以看出对 JVM 的优化主要在于: JVM-- 垃
圾收集。
注意: Heap 大小并不决定进程的内存使用量。进程的内存使用量要大于 -Xmx 定义的值,
因为 Java 为其他任务分配内存,例如每个线程的 Stack 等。

日常遇到的OOM和频繁发生GC 情况分析

java.lang.OutOfMemoryError: Java heap space
heap 空间不足,可能是 -Xmx 配得过大,或者系统内存不足或泄漏


java.lang.OutOfMemoryError: PermGen space
持久代内存不足,存在大量系统类被加载或 jpa 等架构频繁使用,需要增加 Perm的内存配置


java.lang.OutOfMemoryError:unable to create native thread
空闲内存不足以建立新的线程,减少 max-threads 的配置,增加空闲内存数量

为什么一些程序频繁发生 GC ?有如下原因:
1. 程序内调用了 System.gc() 或 Runtime.gc() 。
2. 一些中间件软件调用自己的 GC 方法,此时需要设置参数禁止这些 GC 。
3. Java 的 Heap 太小,一般默认的 Heap 值都很小。
4. 频繁实例化对象, Release 对象。此时尽量保存并重用对象,例如使用StringBuffer() 和 String() 。
5. 如果你发现每次 GC 后, Heap 的剩余空间会是总空间的 50% ,这表示你的 Heap
处于健康状态。
在 Resin 中对 JVM 的优化能很好的提高 Resin 的性能,通过这些基本知识使你对Resin 中 JVM 的优化更有把握。
参考文章:
http://blog.csdn.net/tyrone1979/archive/2006/09/25/1274458.aspx
http://www.caucho.com/resin-3.0/performance/jvm-tuning.xtp#garbage-collection

Resin中除JVM外的优化
在实际的生产环境中,以下三个东西经常用到,所以在这里提一下,也算是简单的优化。
<thread-max>512</thread-max>
最大线程数影响 resin 的系统负载能力以及 java 进程的内存占用
<keepalive-max>128</keepalive-max>
keepalive 的最大数量,对网络性能有影响
js/html/css/jpg/gif 等静态文件由 nginx 提供服务,剩下的由nginx以upstream方式代理到后端resin处理,以减少resin 提供这些静态文件访问的性能问题。
R esin 及 jvm 优化,是一项基于提供服务的应用上进行一段相对长时间的测试进行,由于每个项目都有其自身特点,只有根据这些特点来进行优化,才能把该项目配置得更好 ,不可能硬套到其它项目上 。



本文转自 00_yatou 51CTO博客,原文链接:http://blog.51cto.com/ql0722/1655993,如需转载请自行联系原作者

1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作。 在充分理解了垃圾收集算法和执行过程后,才能有效的优化它的性能。有些垃圾收集专用于特殊的应用程序。比如,实时应用程序主要是为了避免垃圾收集中断,而大多数OLTP应用程序则注重整体效率。理解了应用程序的工作负荷和jvm支持的垃圾收集算法,便可以进行优化配置垃圾收集器。 垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。gc首先要判断该对象是否是时候可以收集。两种常用的方法是引用计数和对象引用遍历。 1.1.引用计数 引用计数存储对特定对象的所有引用数,也就是说,当应用程序创建引用以及引用超出范围时,jvm必须适当增减引用数。当某对象的引用数为0时,便可以进行垃圾收集。 1.2.对象引用遍历 早期的jvm使用引用计数,现在大多数jvm采用对象引用遍历。对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。在对象遍历阶段,gc必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。 下一步,gc要删除不可到达的对象。删除时,有些gc只是简单的扫描堆栈,删除未标记的未标记的对象,并释放它们的内存以生成新的对象,这叫做清除(sweeping)。这种方法的问题在于内存会分成好多小段,而它们不足以用于新的对象,但是组合起来却很大。因此,许多gc可以重新组织内存中的对象,并进行压缩(compact),形成可利用的空间。 为此,gc需要停止其他的活动活动。这种方法意味着所有与应用程序相关的工作停止,只有gc运行。结果,在响应期间增减了许多混杂请求。另外,更复杂的gc不断增加或同时运行以减少或者清除应用程序的中断。有的gc使用单线程完成这项工作,有的则采用多线程以增加效率。 2.几种垃圾回收机制 2.1.标记-清除收集器 这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。 2.2.标记-压缩收集器 有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。 2.3.复制收集器 这种收集器将堆栈分为两个域,常称为半空间。每次仅使用一半的空间,jvm生成的新对象则放在另一半空间中。gc运行时,它把可到达对象复制到另一半空间,从而压缩了堆栈。这种方法适用于短生存期的对象,持续复制长生存期的对象则导致效率降低。 2.4.增量收集器 增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。 2.5.分代收集器 这种收集器把堆栈分为两个或多个域,用以存放不同寿命的对象。jvm生成的新对象一般放在其中的某个域中。过一段时间,继续存在的对象将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。 2.6.并发收集器 并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时)一般都不得不停止其他操作以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。 2.7.并行收集器 并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多cpu机器上使用多线程技术可以显著的提高java应用程序的可扩展性。 3.Sun HotSpot 1.4.1 JVM堆大小的调整 Sun HotSpot 1.4.1使用分代收集器,它把堆分为三个主要的域:新域、旧域以及永久域。Jvm生成的所有新对象放在新域中。一旦对象经历了一定数量的垃圾收集循环后,便获得使用期并进入旧域。在永久域中jvm则存储class和method对象。就配置而言,永久域是一个独立域并且不认为是堆的一部分。 下面介绍如何控制这些域的大小。可使用-Xms和-Xmx 控制整个堆的原始大小或最大值。 下面的命令是把初始大小设置为128M: java –Xms128m –Xmx256m为控制新域的大小,可使用-XX:NewRatio设置新域在堆中所占的比例。 下面的命令把整个堆设置成128m,新域比率设置成3,即新域与旧域比例为1:3,新域为堆的1/4或32M: java –Xms128m –X
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值