《深入理解java虚拟机》读书笔记六 【调优案例分析】

时间:2022-12-28 13:02:47

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: