• JVM调优案例


    高性能硬件上的程序部署策略:
    硬件系统为4个CPU、16GB物理内存,操作系统为64位CentOS,Resin作为web服务器。管理员选用了64位的JDK1.5,并通过-Xmx和-Xms的参数将Java堆固定在12GB。
     
    高性能硬件上部署程序,目前主要由两种方式:
    1.通过64位JDK来使用大内存
    2.使用若干个32位虚拟机建立逻辑集群来利用硬件资源
     
    对于用户交互性强、对停顿时间敏感的系统,可以给Java虚拟机分配超大堆的前提是有把握应用程序的Full GC频率控制得足够低,至少要低到不会影响用户使用,譬如十几个小时甚至一天才出现一次Full GC,这样可以通过在深夜执行定时任务的方式触发Full GC甚至自动重启服务器来保持内存可用空间在一个稳定的水平
     
    控制Full GC频率的关键是看应用中绝大多数对象能否符合 朝生夕灭 的原则,即大多数对象的生存时间不应太长,尤其是不能有成批量的、长生存时间的大对象产生,这样才能保障老年代空间的稳定
     
    如果计划使用64位JDK来管理大内存,还需要考虑下面可能面临的问题:
    1.内存回收导致长时间停顿
    2.现阶段,64位JDK的性能测试结果普遍低于32位JDK
    3.需要保证程序足够稳定,因为这种应用要是产生堆溢出几乎就无法产生堆转储快照,哪怕产生了快照也几乎无法进行分析
    4.相同程序在64位JDK消耗的内存一般比32位JDK大,这是由于指针膨胀,以及数据类型对齐补白等因素导致的
     
    如果使用第二种方式,使用多个32位虚拟机建立逻辑集群来利用硬件资源。具体做法是在一台物理机器上启动多个应用服务器进程,每个服务器进程分配不同端口,然后在前端搭建一个负载均衡器,以反向代理的方式来分配访问请求。
    使用第二种逻辑集群的方式部署程序,可能会遇到下面一些问题:
    1.尽量避免节点竞争全局的资源,最典型的就是磁盘竞争,各个节点如果同时访问某个磁盘文件的话,容易导致IO异常
    2.很难最高效领某些资源池,比如连接池,一般都是在各个节点建立自己独立的连接池,这样有可能导致一些节点池满了而另外一些节点仍有较多空余。尽管可以使用集中式的JNDI,但这个有一定复杂性并且可能带来额外的性能开销
    3.各个节点仍然不可避免地受到32位的内存限制,在32位Windows平台中每个进程只能使用2GB内存,考虑到堆以外的内存开销,堆一般最多只能开到1.5GB。在某些Linux或Uninx系统中,可以提升到3GB乃至接近4GB的内存,但32位中仍然受最高4G内存的限制
    4.大量使用本地缓存的应用,在逻辑集群中会造成较大的内存浪费,因为每个逻辑节点上都有一份缓存,这时候可以考虑把本地缓存改为集中式缓存
     
    回到上面的案例中,最后的部署方案调整为建立5个32位JDK的逻辑集群,每个进程按2GB内存计算(堆固定为1.5),占用了10GB内存。另外建立一个Apache服务作为前端均衡代理访问门户。考虑到用户对响应速度比较关心,并且文档服务的主要压力集中在磁盘和内存访问,CPU资源敏感度较低,因此改为CMS收集器进行垃圾回收。
  • 相关阅读:
    【原理】【重点】异步回调的一些实现策略
    上下文传递
    洋码头全异步服务框架
    秒杀系统架构优化思路
    从urllib2的内存泄露看python的GC python引用计数 对象的引用数 循环引用
    jvisualvm All-in-One Java Troubleshooting Tool
    小心踩雷,一次Java内存泄漏排查实战
    django 请求处理流程 链路追踪
    存储过程
    Dijkstra's algorithm
  • 原文地址:https://www.cnblogs.com/gqymy/p/12169326.html
Copyright © 2020-2023  润新知