关于java性能的小笔记

 

一、大规模高并发访问的性能分析:

1.应用服务器中JVM的优化:

在安装JDK后,有两个JVM虚拟机,分别是server jvm和 client jvm。其中server jvm比client jvm进行了更多的优化,所以在开发和测试Web应用系统时,应用指定服务器的jvm虚拟机为server jvm。

       启动client jvm 和server jvm的方式:

       Java –client yourclass

       Java –server yourclass

       其中client jvm是默认的启动方式。在tomcat服务器中,通常会有如下两种设置jvm虚拟机的方式:

●   %java_home%/jre/bin/client/jvm.dll

●   %java_home%/jre/bin/server/jvm.dll

Jvm动态库有client和server两个版本,分别针对桌面应用和服务器应用做了相应优化,其中client版本加载速度较快,server版本加载速度较慢但运行起来较快。一般在tomcat服务器中,应使用server版本。

 

2.  JVM虚拟机中对字节码优化的策略:

Server jvm和client jvm对字节码优化的策略不同:

●Client主要优化对用户交互的相应速度。

●Server主要优化后台运行的代码。

使用server模式可以提高性能,启动比client模式慢,长期运行则比client模式快。当该参数不指定时,虚拟机启动检测主机是否为服务器,如果是,则以server模式启动,否则以client模式启动。J2SE 5.0检测的根据是至少2个CPU和最低2GB内存。

3.  堆大小设置:

JVM中最大堆大小有三方面限制:相关操作系统的数据模型(32bit还是64bit)限制;系统的可用物理内存限制。在32位系统下,一般限制在1.5-2G,在64位系统下,操作系统对内存无限制。

常用的典型设置如下:

●Java –Xmx3550m –Xms3550m –Xmn2g –Xss128k

●-Xmx3550m: 设置JVM最大可用内存为3550。

 

-Xms3550m:设置JVM初始化内存为3550M。此值可以设置于-Xmx相同,以避免每次垃圾回收完成后JVM重新分配内存。

-Xmn2g:设置年轻代大小为2G。整个堆大小=年轻代大小+年老代大小+持久代大小。持久代大小一般固定大小为64M,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun 官方推荐配置为整个堆的3/8。基于对对象生命周期分析后得出的垃圾回收算法,把对象分为年轻代,年老代,持久代,对不同的生命周期的对象使用不同的算法(上述方式中的一个)进行回收。现在的垃圾回收器(从J2SE 1.2开始)都是使用此算法的。

-Xss128k:设置每个线程的堆栈大小。从JDK5.0每个堆线程大小为1M,以前每个线程堆大小为256K。可根据具体应用调整线程所需内存大小。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,通常值在3000~5000左右。

4.回收器选择:

       在JVM中给三种回收器的选择:串行收集器、并行收集器、并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器。默认情况下,在JDK5.0以前都是使用串行收集器,如果想使用其他收集器需要在启动时加入相应参数,从JDK5.0以后,JVM会根据当前系统配置进行判断。

       并行收集器主要以达到一定的吞吐量为目标,适用于科学技术和后台处理等,典型配置如下:

java-Xmx2800m-Xms800m-Xmn2g-Xss128k-XX:+UserParallelGC-XX:ParallelGCThreads=20-XX:+UserParallelOldGC

    ●-XX:+UserParallelGC:选择垃圾收集器为并行收集器。此配置仅对年轻代有效。即上述配置下,年轻代使用并发收集,而年老代仍旧使用串行收集。

       ●-XX:ParallelGCThreads=20:配置并行收集器的线程数,即同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。

       ●-XX:+UserParallelOldGC:配置年老代垃圾收集方式为并行收集,JDK6.0支持对年老代并行收集。

       并发收集器主要是保证系统的响应时间,减少垃圾收集时的停顿时间。适用于应用服务器、电信领域等。典型配置如下:

Java-Xmx3550m-Xms3550-Xmn2g-Xss128k-XX:ParallelGCThreads=20-XX:+UserConcMarkSweepGC-XX:+UserParNewGC

       ●-XX:+UseConcMarkSweepGC:设置年老代为并发收集。

       ●-XX:+UseParNewGC:设置年轻代为并行收集。可与CMS收集同时使用。从JDK5.0开始,JVM会根据系统配置自行设置,所以无需再设置此值。

5.年轻代大小选择:
       响应时间优先的应用:年轻代尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择)。在此种情况下,年轻代收集发生的频率也是最小的。同时减少到达年老代对象。

吞吐量优先的应用:年期代尽可能的设置大,可能达到Gbit的程度。因为对响应时间没有要求,垃圾收集可以并行进行,一般适合8CPU以上的应用。

6.年老代大小选择:

       响应时间优先的应用:年老代使用并发收集器,所以其大小需要小心设置,一般要考虑并发会话率和会话持续时间等一些参数。如果堆设置小了,可能会造成内存碎片、高回收频率以及应用暂停而使用传统的标记清除方式:如果堆大了,则需要较长的收集时间。最优化的方案,一般需要参考以下数据获得:

●    并发垃圾收集信息。

●    持久代并发收集次数

●    传统GC信息

●    花在年轻代和年老代回收上的时间比例

●    减少年轻代和年老代花费的时间,一般会提高应用的效率

吞吐量优先的应用:一般吞吐量优先的应用都有一个很大的年轻代和一个较小的年老代。原因是:这样可以尽可能回收掉大部分短期对象,减少中期的对象。

 

7.较小堆引起的碎片分析:

       因为年老代的并发收集器使用标记、清除算法,所以不会对堆进行压缩。当收集器回收时,它会把相邻的空间进行合并,这样可以分配给较大的对象。但是当堆空间较小时,运行一段时间以后,就会出现“碎片”,如果并发收集找不到足够的空间,那么并发收集器将会停止,然后使用传统的标记、清除方式进行回收。如果出现“碎片”,可能需要进行如下配置:

       ●-XX:+UserCMSCompactAtFullCollection:使用并发收集器时,开启对年老代的压缩。

       ●-XX:CMSFullGCsBeforeCompaction=0:上面配置开启的情况下,这里设置多少次Full GC后,对年老代进行压缩。

8.在实际编程中对内存的优化:

       应用java开发的系统给人的印象是占内存,其实从理论上来讲,java开发的系统并不比其他语言开发的系统更占用内存,这就需要子啊编程时注意优化内存。

       ●不要使用new Boolean().

       ●不要使用new Integer()

    ●用StringBuffer代替字符串相加

    ●过滥使用哈希表

    ●避免过深的类层次结构和过深的方法调用。因为这两者都是非常占用内存的(特别是方法调用更是堆栈空间的消耗大户)

    ●变量只用在用到它的时候才定义和实例化

    ●尽量避免使用static变量,类内私有常量可以有final来代替

    ●尽早释放无用对象的引用

    ●尽量少用finalize函数。它会增加GC的工作量

    ●尽量避免在类的默认构造器中创建和初始化大量的对象,防止在调用其构造器时造成不必要的内存资源浪费

    ●尽量避免强制显示申请数组空间

    ●尽量做远程方法调用类应用开发时使用瞬间值变量,除非远程调用端需要获取该瞬间值变量的值。

    ●尽量在合适的场景下使用对象池技术以提高系统性能

9.集群与负载均衡

    在单一的服务器上执行某些应用程序会出现一些重大问题。当网站成功建成并开始接受大量请求时,单一服务器终究无法满足需要处理的负荷量,所以就显得有点力不从心了。另外一个常见的问题是会产生单点故障,如果该服务器坏掉,那么网站就立刻无法运行了。不论是因为要有较佳的扩充性还是要有容错能力。都希望在一台以上的服务器计算机上执行该应用程序,这就需要用到集群技术。

    集群(luster)一组独立的计算机系统构成一个松耦合的多处理系统,他们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送,实现分布式计算机。

    集群系统主要解决下面几个问题:

●    高可靠性(HA):利用集群管理软件,当主服务器故障时,备份服务器能够自动接管主服务器的工作,并及时切换过去,以实现对用户的不间断服务。

●    高性能计算(HP):即充分利用集群中的每一台计算机的资源,实现复杂运算的并行处理,通常用于科学计算领域,如基因分析,化学分析。

●    负载平衡:即把负载压力根据某种算法合理分配到集群中每一台计算机上,以减轻服务器压力,降低对主服务器的硬件和软件需求。

●    负载均衡(oad Balance):集群就是一组连在一起的计算机,从外部看它是一个系统,各节点可以是不同的操作系统或不同硬件构成的计算机。如一个提供Web服务的集群,从外界来看是一个大的WEB服务器。不过集群的节点也可以单独提供服务。在现有网络结构之上,负载均衡提供了一种廉价有效的方法扩展服务器带宽和增加吞吐量,加强网络数据处理能力,提高网络的灵活性和可用性。

目前比较常用的负载均衡技术主要如下:

1.基于DNS的负载均衡

a)        通过DNS服务中的随机名字来实现负载均衡,在DNS服务器中,可以为多个不同的地址配置同一个名字,而最终查询这个名字的客户机讲在解析这个名字时得到其中一个地址,因此,对于同一个名字,不同的客户机会得到不同的地址,他们也就访问不同地址上的WEB应用服务器,从而达到负载均衡的目的。

反向代理负载均衡
上一篇:Submit solution(1200)


下一篇:防抖和节流