关于java性能的小笔记

简介:   一、大规模高并发访问的性能分析: 1.应用服务器中JVM的优化: 在安装JDK后,有两个JVM虚拟机,分别是server jvm和 client jvm。其中server jvm比client jvm进行了更多的优化,所以在开发和测试Web应用系统时,应用指定服务器的jvm虚拟机为server jvm。        启动client jvm 和server jvm的方式:
 

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

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应用服务器,从而达到负载均衡的目的。

反向代理负载均衡
相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
12天前
|
Java
Java基础—笔记—static篇
`static`关键字用于声明静态变量和方法,在类加载时初始化,只有一份共享内存。静态变量可通过类名或对象访问,但推荐使用类名。静态方法无`this`,不能访问实例成员,常用于工具类。静态代码块在类加载时执行一次,用于初始化静态成员。
10 0
|
12天前
|
Java API 索引
Java基础—笔记—String篇
本文介绍了Java中的`String`类、包的管理和API文档的使用。包用于分类管理Java程序,同包下类无需导包,不同包需导入。使用API时,可按类名搜索、查看包、介绍、构造器和方法。方法命名能暗示其功能,注意参数和返回值。`String`创建有两种方式:双引号创建(常量池,共享)和构造器`new`(每次新建对象)。此外,列举了`String`的常用方法,如`length()`、`charAt()`、`equals()`、`substring()`等。
14 0
|
19天前
|
移动开发 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【4月更文挑战第3天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin的兴起,其在Android开发中的地位逐渐上升,但关于其与Java在性能方面的对比,尚无明确共识。本文通过深入分析并结合实际测试数据,探讨了Kotlin与Java在Android平台上的性能表现,揭示了在不同场景下两者的差异及其对应用性能的潜在影响,为开发者在选择编程语言时提供参考依据。
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第30天】 随着Kotlin成为开发Android应用的首选语言,开发者社区对于其性能表现持续关注。本文通过深入分析与基准测试,探讨Kotlin与Java在Android平台上的性能差异,揭示两种语言在编译效率、运行时性能和内存消耗方面的具体表现,并提供优化建议。我们的目标是为Android开发者提供科学依据,帮助他们在项目实践中做出明智的编程语言选择。
|
1月前
|
安全 Java Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第24天】在移动开发领域,性能优化一直是开发者关注的焦点。随着Kotlin在Android开发中的普及,了解其与Java在性能方面的差异变得尤为重要。本文通过深入分析和对比两种语言的运行效率、启动时间、内存消耗等关键指标,揭示了Kotlin在实际项目中可能带来的性能影响,并提供了针对性的优化建议。
29 0
|
1月前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--希尔排序
数据结构与算法(Java篇)笔记--希尔排序
|
27天前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
在开发高性能的Android应用时,选择合适的编程语言至关重要。近年来,Kotlin因其简洁性和功能性受到开发者的青睐,但其性能是否与传统的Java相比有所不足?本文通过对比分析Kotlin与Java在Android平台上的运行效率,揭示二者在编译速度、运行时性能及资源消耗方面的具体差异,并探讨在实际项目中如何做出最佳选择。
17 4
|
1月前
|
Java 编译器 Android开发
构建高效Android应用:探究Kotlin与Java的性能差异
【2月更文挑战第24天】 在移动开发领域,性能优化一直是开发者关注的重点。随着Kotlin的兴起,许多Android开发者开始从传统的Java转向Kotlin进行应用开发。本文将深入探讨Kotlin与Java在Android平台上的性能表现,通过对比分析两者在编译效率、运行时性能和内存消耗等方面的差异。我们将基于实际案例研究,为开发者提供选择合适开发语言的数据支持,并分享一些提升应用性能的最佳实践。
|
7天前
|
SQL 缓存 Java
Java数据库连接池:优化数据库访问性能
【4月更文挑战第16天】本文探讨了Java数据库连接池的重要性和优势,它能减少延迟、提高效率并增强系统的可伸缩性和稳定性。通过选择如Apache DBCP、C3P0或HikariCP等连接池技术,并进行正确配置和集成,开发者可以优化数据库访问性能。此外,批处理、缓存、索引优化和SQL调整也是提升性能的有效手段。掌握数据库连接池的使用是优化Java企业级应用的关键。
|
10天前
|
存储 Java 测试技术
Java 21革命性升级:探索分代ZGC的性能奇迹
Java 21革命性升级:探索分代ZGC的性能奇迹
13 0

热门文章

最新文章