1.高性能硬件上的程序部署策略
在线文档类型网站,用户交互性强,对停顿时间敏感,网站形式的应用,主要对象的生命周期是请求级或页面级的“朝生夕灭”的对象,无需进入老年代,最好在MinorGC的时候就回收,会话级和全局级的长生命对象很少。
硬件资源:4个CPU,16GB物理内存,操作系统64位CentOS5.4,web服务器Resin。
软件设置:64位JDK1.5,Xmx=Xms=12GB。
问题:网站每隔十几分钟出现十几秒的停顿。
分析:监控服务器运行状况后发现,GC停顿导致,虚拟机在server模式下选择的是Parallel Scavenge收集器,回收12GB堆的Full GC时间14秒。另外文档序列化产生的大对象进入老年代。
高性能硬件上的程序部署策略有两种:
>通过64位jdk使用大内存,控制Full GC的频率,如一天一次,将内存可用空间保持在一个稳定的水平。
>使用若干个32位虚拟机建立逻辑集群来利用硬件资源,在一台物理机器上启动多个应用服务器进程,给每个服务器进程分配不同的端口,然后在前端搭建一个负载均衡器,以反向代理的方式来分配访问请求。
解决方案:5个32位JDK的逻辑集群,每个进程2GB内存,其中堆1.5GB,建立一个Apache服务作为前端均衡代理访问门户,改为CMS收集器。
2.集群间同步导致的内存溢出
B/S的MIS系统
硬件:2个CPU,8GB内存的HP小型机
服务器:WebLogic9.2,每台机器启动了3个WebLogic实例,构成一个6个节点的亲合式集群,节点之间没有session同步。
有一些需求要实现部分数据在各个节点共享,刚开始这些数据存放在DB,由于读写频繁,竞争激烈,对性能影响很大,换成了JBossCache构建的全局缓存。
问题:服务器使用一段时间后,不定期多次出现OOM
解决:代码是否有内存泄漏,-XX:+HeapDumpOnOutOfMemoryError,dump文件有大量org.jgroups.protocols.pbcast.NAKACK对象
JBossCache的缺陷,读可以频繁,频繁写导致重发数据在内存中不断堆积,产生溢出,当网络情况不能满足传输要求的时候。
3.堆外内存导致的溢出错误
B/S的电子考试系统,逆向AJAX技术,CometD 1.1.1服务端推送框架,Jetty7.1.4服务器
硬件:普通PC机,Core i5 CPU,4GB内存,32 win操作系统
问题:服务器不定时抛出内存溢出异常
解决:开大堆内存到1.6GB,没用;-XX:HeapDumpOnOutOfMemoryError,没反应;挂jstat,GC也不频繁。
系统日志中显示:at org.eclipse.jetty.io.nio.DirectNIOBuffer.<init> 大量的NOI操作需要用到Direct Memory
Direct Memory只剩下0.4GB空间,内存溢出。Direct Memory空间不足时,只能等待老年代满了后Full GC时清理掉内存的废弃对象,否则,只能等到内存溢出时,先catch掉,再在catch块里大喊System.gc()。
除了java堆和方法区,还有一些区域的内存总和受到操作系统进程最大内存的限制:
》Direct Memory,-XX:MaxDirectMemorySize调整大小
》线程堆栈:通过-Xss调整大小,无法分配新的栈时,抛出*Error,无法建立新的线城时,抛出OutOfMemoryError
》Socket缓冲区:Receive区和Send区分别占用37kb,25kb,连接太多时,会抛出IOException:Too many open files
》JNI代码:如果JNI调用本地库,本地库使用的内存也不在堆中
》虚拟机和GC: