Java堆是指在程序运行时分配给对象生存的空间。通过-mx/-Xmx和-ms/-Xms来设置起始堆的大小和最大堆的大小。根据自己JDK的版本和厂家决定使用-mx和-ms或-Xmx和-Xms。Java堆大小决定了垃圾回收的频度和速度,Java堆越大,垃圾回收的频度越低,速度越慢。同理,Java堆越小,垃圾回收的频度越高,速度越快。要想设置比较理想的参数,还是需要了解一些基础知识的。 Java堆的最大值不能太大,这样会造成系统内存被频繁的交换和分页。所以最大内存必须低于物理内存减去其他应用程序和进程需要的内存。而且堆设置的太大,造成垃圾回收的时间过长,这样将得不偿失,极大的影响程序的性能。以下是一些经常使用的参数设置:

  1) 设置-Xms等于-XmX的值;

  2) 估计内存中存活对象所占的空间的大小,设置-Xms等于此值,-Xmx四倍于此值;

  3) 设置-Xms等于-Xmx的1/2大小;

  4) 设置-Xms介于-Xmx的1/10到1/4之间;
 
  5) 使用默认的设置。

  大家需要根据自己的运行程序的具体使用场景,来确定最适合自己的参数设置。 除了-Xms和-Xmx两个最重要的参数外,还有很多可能会用到的参数,这些参数通常强烈的依赖于垃圾收集的算法,所以可能因为JDK的版本和厂家而有所不同。但这些参数一般在Web开发中用的比较少,我就不做详细介绍了。在实际的应用中注意设置-Xms和-Xmx使其尽可能的优化应用程序就行了。对于性能要求很高的程序,就需要自己再多研究研究Java虚拟机和垃圾收集算法的机制了。可以看看曹晓钢翻译的《深入Java虚拟机》一书。
Java程序性能调优的基本知识和JDK调优

  基本知识

  1.1 性能是什么

  在性能调优之前,我们首先来了解一下性能是什么?关于性能,我想每个学习过Java的人都能列出几点,甚至可以夸夸其谈。在《Java TM Platform Performance》一书中,定义了如下五个方面来作为评判性能的标准:

  1) 运算的性能——哪一个算法的执行性能最好?

  2) 内存的分配——程序运行时需要耗费多少内存?

  3) 启动的时间——程序启动需要多长时间?这在Web项目中的影响不大,但要注意部分程序需要部署或运行在客户端时的情形(比如applet程序)。

  4) 程序的可伸缩性——在压力负载的情况下,程序的性能如何?

  5) 性能的感知——用户在什么情况下会觉得程序的性能不好?

  以上五个方面,在具体的使用场景可以有选择的去评判。至于这五方面的性能调优,在后续的章节中将会陆续的给以相应的性能调优策略。
 
  1.2 调优的规则

  我们只需要关心对我们程序有影响,可以察觉到的性能问题,而不是每一个类中的每一个方法我们都需要想方设法的提高性能。如果程序的性能没有达到我们所期望的要求,我们才需要考虑如何优化性能。同样的,晦涩的代码虽然提高了程序的性能,但同时可能带给我们的是维护的噩梦。我们需要折中的考虑以上两种情况,使得程序的代码是优美的,并且运行的足够快,达到客户所期望的性能要求。

  优化代码甚至会导致不良的结果,Donald Knuth(一位比较牛比较有影响的人物,具体是谁,我也忘了,谁知道,可以告诉我一下,谢谢!)曾说过,Premature optimization is the root of all evil”。在开始性能调优前,需要先指出不优化代码的一些理由。

  1) 如果优化的代码已经正常工作,优化后可能会引入新的bug

  2) 优化代码趋向于使代码更难理解和维护;

  3) 在一个平台上优化的代码,在另一个平台上可能更糟;

  4) 花费很多时间在代码的优化上,提高了很少的性能,却导致了晦涩的代码。 确实,在优化前,我们必须认真的考虑是否值得去优化。

  1.3 调优的步骤

  一般我们提高应用程序的性能划分为以下几个步骤:

  1) 明确应用程序的性能指标,怎样才符合期望的性能需求;

  2) 在目标平台进行测试;

  3) 如果性能已经达到性能指标,Stop

  4) 查性能瓶颈;

  5) 修改性能瓶颈;

  6) 返回到第2步。

  JDK调优

  2.1 选择合适的JDK版本

  不同版本的JDK,甚至不同厂家的JDK可能都存在着很大的差异,对于性能优化的程度不同。一般来说,尽可能选择最新发布的稳定的JDK版本。最新的稳定的JDK版本相对以前的JDK版本都会做一些bug的修改和性能的优化工作。

  2.2 垃圾收集Java堆的优化

  垃圾收集就是自动释放不再被程序所使用的对象的过程。当一个对象不再被程序所引用时,它所引用的堆空间可以被回收,以便被后续的新对象所使用。垃圾收集器必须能够断定哪些对象是不再被引用的,并且能够把它们所占据的堆空间释放出来。如果对象不再被使用,但还有被程序所引用,这时是不能被垃圾收集器所回收的,此时就是所谓的内存泄漏。监控应用程序是否发生了内存泄漏,有一个非常优秀的监控工具推荐给大家——Quest公司的JProbe工具,使用它来观察程序运行期的内存变化,并可产生内存快照,从而分析并定位内存泄漏的确切位置,可以精确定位到源码内。这个工具的使用我在后续的章节中还会做具体介绍。

  Java堆是指在程序运行时分配给对象生存的空间。通过-mx/-Xmx-ms/-Xms来设置起始堆的大小和最大堆的大小。根据自己JDK的版本和厂家决定使用-mx-ms-Xmxphp的工作流程-XmsJava堆大小决定了垃圾回收的频度和速度,Java堆越大,垃圾回收的频度越低,速度越慢。同理,Java堆越小,垃圾回收的频度越高,速度越快。要想设置比较理想的参数,还是需要了解一些基础知识的。 Java堆的最大值不能太大,这样会造成系统内存被频繁的交换和分页。所以最大内存必须低于物理内存减去其他应用程序和进程需要的内存。而且堆设置的太大,造成垃圾回收的时间过长,这样将得不偿失,极大的影响程序的性能。以下是一些经常使用的参数设置:

  1) 设置-Xms等于-XmX的值;

  2) 估计内存中存活对象所占的空间的大小,设置-Xms等于此值,-Xmx四倍于此值;

  3) 设置-Xms等于-Xmx1/2大小;

  4) 设置-Xms介于-Xmx1/101/4之间;
 
  5) 使用默认的设置。

  大家需要根据自己的运行程序的具体使用场景,来确定最适合自己的参数设置。 除了-Xms-Xmx两个最重要的参数外,还有很多可能会用到的参数,这些参数通常强烈的依赖于垃圾收集的算法,所以可能因为JDK的版本和厂家而有所不同。但这些参数一般在Web开发中用的比较少,我就不做详细介绍了。在实际的应用中注意设置-Xms-Xmx使其尽可能的优化应用程序就行了。对于性能要求很高的程序,就需要自己再多研究研究Java虚拟机和垃圾收集算法的机制了。可以看看曹晓钢翻译的《深入Java虚拟机》一书。
Web 应用程序调优指南时间:2009-09-09 22:45:36来源:网络 作者:未知 点击:120次
一.成功的应用都是相似的,失败的应用各有各的失败
一.成功的应用都是相似的,失败的应用各有各的失败
对于Web应用来说,影响性能的集中体现在网络/CPU/内存/IO/数据库/缓存这6个环节的处理上。一个稳定应用的特征应该包括:
1.      网络流量平稳,连接数保持稳定
2.      低CPU负载
3.      内存曲线平稳
4.      IO高响应
5.      数据库的低负载,高响应
简单的来说,对于每个不稳定的应用来说,都会有一个瓶颈,通过以上的工具分析,加上
自己的判断,到那个瓶颈,解决它!
我们可以通过以下监控工具可监控到应用的各项指标
1.      网络监控工具 Cacti ,可以监控到整个服务器的流量/硬盘/CPU负载等情况
2.      JVM 监控 JConsole (JDK 1.5 以上版本自带), %JAVA_HOME%\bin\jconsole
Java 启动加上一下参数:
-Dcom.sun.management.jmxremote.port=5004 (监控端口)
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
3.      Visual VM (JDK 1.6_07 以上版本自带) %JAVA_HOME%\bin\jvisualvm
配置方法同JConsole , Visual VM 比 JConsole 多了一个实用功能Thead Dump.
4.      Kill -3 来获取 Thead Dump
TheadDump可以很清晰的告诉你JVM当前正在做什么,内存里有哪些进程,是否有死锁。重点观察RUNNABLE 和 LOCK 是否有死锁。
5.      数据库查看
MySql 的 show processlist命令
 
二.调优手段和策略
1.      网络层优化
不同类型的应用所能承受的网络负载各不相同,对于长连接应用来说,比如下载应用,所能承受的连接数就相对低,对于短链接应用,比如计数应用,所能承受的连接数就相对高,对于一般有数据库的应用来说,每秒的连接数保持在700以下都是没问题的。
这里调优的方面包括:
1)  Linux可以优化网络的TCP参数,提高网络的响应,
2)  增加服务器实现负载均衡,目的降低单台服务器流量
3)  优化程序,尽可能的减少处理的时间,如果一定有长时间处理的场景,可以采用异步方式处理。先返回一个请求ID,然后客户端再通过这个ID来获得结果。
2.      CPU优化
就目前的硬件环境来看,CPU都不会是一个瓶颈。如果CPU出现负载高,基本上都是程序处理不当引起,比如有深度递归或者循环或者频繁写磁盘,一旦出现高负载,会引起一系列的连锁反应,响应降低,连接数增加。
          这个环节主要是优化程序:
1)  减少循环和递归
2)  减少synchronized 的用法。对于多服务器场景,要实现锁机制,用synchronized 不一定适合。Synchronized 使用不当,极容易造成死锁。
3)  减少死锁发生的可能性。JConsole提供了一个检测死锁的方法,TheadDump 也可以分析死锁。
3.      内存优化
对于Java应用来说,内存调优是关键。先来认识一下Java内存的构成和垃圾回收的机制:
堆是应用程序使用的主要部分,一旦堆满,应用程序就会抛出Out Of Memory错误。具体关于堆的构成以及垃圾回收算法,可以参考文档:
aleung.blogbus/logs/4712392.html
这个环节的优化:
1)      增加JVM内存,使得可使用的堆内存尽可能多,延长垃圾回收的时间。需要注意的是,
一般来说,回收1G内存所需要的时间是7秒左右,如果这个时间访问量比较高,极容易导致应用停止响应,所以并非是越大内存越好。