Java SE和Java EE应用的性能调优
凡事预则立,不预则废,和很多事情一样。Java性能调优的成功。离不开行动计划、方法或策略以及特定的领域背景知识。为了在Java性能调优工作中有所成就。你得超越“花似雾中看”的状态,进入“悠然见南山”或者已然是“一览众山小”的境地。
这三个境地的说法可能让你有些糊涂吧。以下进一步解释。
- 花似雾中看(I don't know what I don't know)。
有时候下达的任务会涉及你所不熟悉的问题域。理解陌生问题域首先面临的困难就是怎样竭尽所能地学会它,由于你对它差点儿一无所知。对于这类问题域。你有很多东西不了解,或者不知道重点。
换句话说,这个问题域有哪些东西须要了解,你还傻傻看不清楚。这个阶段就是“花似雾中看”。
- 悠然见南山(I know what I don't know)。刚进入不熟悉的问题域时,你对它知之甚少,随着时间的推移,你对它的很多重要方面都已有所认识,仅仅是对重要的详细细节还缺乏了解。这时。你能够算是刚刚“见南山”。
- 一览众山小(I already know what I need to know)。
还有些时候,你对任务的问题域很熟悉。或者已经具有该领域所必备的技能和知识,是这方面的专家。或者你对问题域足够了解,处理起来得心应手。比方你已经掌握了必要的知识,解决问题游刃有余。假设达到这个境地。那就意味着你已经是“一览众山小”了。
通常觉得,传统的软件开发过程主要包含4个阶段:分析、设计、编码和測试。如图1-1所看到的。
图1-1 传统软件开发过程
替换图字: start:開始; analysis:分析; design:设计; code:编码; test:測试;
quality:质量合格?; yes:是; no:否; deploy:部署
分析是开发过程的第一步,用于评估需求、权衡各种架构的利弊以及构思高层抽象。设计则根据分析阶段的基本架构和高层抽象,进行更精细的抽象并着手考虑详细实现。编码自然就是设计的实现。编码之后是測试。用以验证实现是否合乎应用需求。
值得注意的是。測试阶段通常仅仅包含功能測试。即检验应用的运行是否合乎需求规格。一旦測试完毕。应用就能够公布给客户了。
遵循这样的传统软件开发过程的应用。通常要到測试或即将公布时才会关注性能或扩展性。
为了解决问题。Wilson和Kesselman对传统软件开发过程做了些补充,在传统开发模型基础上引入了性能測试分析阶段。參见他们的畅销书Java Platform Performance。
他们建议在測试阶段之后添加性能測试。并将“性能測试是否通过”设定为产品是否公布的标准。假设达到性能和扩展性标准,应用就能够公布,否则就要转向性能分析。并根据分析结果回到之前的某个或者某些步骤。换句话说,通过性能分析来定位性能问题。Wilson和Kesselman加入的性能測试分析如图1-2所看到的。
图1-2 Wilson和Kesselman加入性能測试分析之后的软件开发过程
替换图字: start:開始; analysis:分析; design:设计; code:编码; performance test:性能測试; performance acceptable:性能測试是否通过; profile:性能分析; yes:是; no:否; deploy:部署
对分析阶段提炼出来的性能需求,Wilson和Kesselman建议以用例(use case)的方式特别标识出来,这有助于在分析阶段制定性能评估指标。只是应用的需求文档中通常都不会明白描写叙述性能或扩展性需求。假设你正在开发的应用还没有明白定义这些需求。那就应该想办法将它们挖掘出来。
拿吞吐量和延迟性需求举例。以下清单列举了挖掘这些需求所要考虑的问题。
- 应用预期的吞吐量是多少?
- 请求和响应之间的延迟预期是多少?
- 应用支持多少并发用户或者并发任务?
- 当并发用户数或并发任务数达到最大时,可接受的吞吐量和延迟是多少?
- 最差情况下的延迟是多少?
- 要使垃圾收集引入的延迟在可容忍范围之内,垃圾收集的频率应该是多少?
需求和相应的用例文档应该回答上述问题,并以此制定基准測试和性能測试,确保应用能够满足性能和扩展性需求。基准測试和性能測试应该在性能測试阶段运行。评估用例时有些用例的风险过高,难以实现,应该在分析阶段后期。通过一些原型、基准測试和微基准測试来减少此类风险。分析结束后再变更决策的代价很高,这种方法能够让你事先对决策进行评估。
软件开发周期中的软件缺陷、低劣设计和糟糕实现发现得越晚,修复的代价就越大,这是一条颠扑不破的金科玉律。减少用例的高风险有助于避免这些代价昂贵的错误。
如今很多应用在开发过程中都会使用自己主动构建和測试。Wilson和Kesselman建议改进软件开发过程。在自己主动构建或測试中进一步加入自己主动性能測试。
自己主动性能測试能够发出通知,比方用电子邮件将性能測试结果(如性能是衰减还是改善,或性能指标的达成度)发送给干系人。这个过程能够将因不满足应用性能指标而失败的測试,以及測试的统计数据自己主动记录到追踪系统。
将性能測试集成到自己主动构建过程中后。每次代码变更提交到源码库时。都能很easy地追踪因变更而导致的性能变化,也就能在软件开发的早期发现性能衰减。
另外。将统计方法和自己主动统计分析加入到自己主动性能測试系统中也值得考虑。运用统计方法能够进一步验证性能測试的结果。
自顶向下和自底向上是两种经常使用的性能分析方法。
顾名思义,自顶向下(Top Down)着眼于应用顶层,从上往下寻找软件栈中的优化机会和问题。相反,自底向上(Bottom
Up)则从软件栈最底层的CPU统计数据(比如CPU缓存未命中率、CPU指令效率)開始,逐渐上升到应用自身的结构或该应用常见的使用方式。应用开发者经常使用自顶向下的方法。而性能问题专家则通常採用自底向上的方法,用以辨别因不同硬件架构、操作系统或不同的Java虚拟机实现所导致的性能差异。如你所想。不同方法能够用来查找不同类型的性能问题。
自顶向下大概是最经常使用的性能调优方法。假设须要更改应用软件栈的顶层代码进行调优,这也是最经常使用的方法。
使用自顶向下的方法时。通常你须要从干系人发现性能问题的负载開始监控应用。应用的配置变化或日常负荷变化可能导致性能减少,这样的情况下。须要持续地监控应用。此外,当应用的性能和扩展性需求发生变化时,应用可能无法满足新的要求。这时也须要监控应用程序的性能。
无论何种原因引起的性能调优。自顶向下的第一步总是对运行在特定负载之下的应用进行监控。监控的范围包含操作系统、Java虚拟机、Java EE容器以及应用的性能測量统计指标。基于监控信息所给出的提示再开展下一步工作,比如JVM垃圾收集器调优、JVM命令行參数调优、操作系统调优,或者应用程序性能分析。
性能分析可能导致应用程序的更改,或者发现第三方库或Java SE类库在实现上的不足。
在不同平台(指底层的CPU架构和数量不同)上进行应用性能调优时。性能专家常使用自底向上的方法。
将应用迁移到其它操作系统上时,也经常使用这样的方法改善性能。在无法更改应用源码时,比如应用已经部署在生产环境中,或者系统供应商为了在竞争中占得先机而必须将性能发挥到极致,也经常会使用这样的方法。
自底向上须要收集和监控最底层CPU的性能统计数据。
监控的CPU统计数据包含运行特定任务所须要的CPU指令数(通常称为路径长度,path length),以及应用在一定负载下运行时的CPU缓存未命中率。尽管还有其它重要的CPU统计数据,但这两项是自底向上中最经常使用的。在一定负载下,应用运行和扩展所需的CPU指令越少。运行得就越快。
减少CPU缓存未命中率也能改善应用的性能,由于CPU缓存失效会导致CPU为了等待从内存获取数据而浪费若干个周期,而减少CPU缓存未命中率,意味着CPU能够减少等待内存数据的时间,应用也就能运行得更快。
自底向上关注的一般是在不更改应用的前提下。改善CPU使用率。假如应用能够更改。自底向上也能为怎样改动应用提供建议。这些更改包含应用源码的变动。如将经常使用的数据移到一起,使得訪问同一条CPU缓存行(CPU cache line)就能获取这些数据,而不用等待从内存中获取数据。
这个改动能够减少CPU缓存未命中率。从而减少CPU等待内存数据的时间。
现代Java虚拟机集成了成熟的JIT编译器,能够在Java应用的运行过程中进行优化,比方根据应用的内存訪问模式或应用特定的代码路径。生成更有效的机器码。也能够调整操作系统的设置来改善性能,比如更改CPU调度算法。或者改动操作系统的等待时间(指操作系统在将应用运行线程迁移到其它CPU硬件线程之前所等待的时间)。
假设你觉得能够用自底向上的方法,那应该先从收集操作系统和JVM的统计数据開始。监控这些统计数据能够为下一步应该关注哪些重点提供线索。
本文内容摘自《Java性能优化权威指南》
Java SE和Java EE应用的性能调优的更多相关文章
- Java生鲜电商平台-API请求性能调优与性能监控
Java生鲜电商平台-API请求性能调优与性能监控 背景 在做性能分析时,API的执行时间是一个显著的指标,这里使用SpringBoot AOP的方式,通过对接口添加简单注解的方式来打印API的执行时 ...
- Java SE、Java EE、Java ME
Java SE(Java Platform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用程序.J ...
- Java SE、Java EE和Java ME有什么区别?
Java现在已不仅仅是一种语言,从广义上说,它代表了一个技术体系.该体系根据应用方向的不同主要分为Java SE.Java EE和Java ME的3个部分. 1998年12月份Sun公司公布的Java ...
- java的几个版本以及jre,jdk等概念——【转载】JDK、Java SE、Java EE、Java ME我该选
我们平时使用的一些软件,有一部分需要Java环境的支持,但是SUN那么多的产品,让人眼花缭乱的版本号,前看后看都差不多的缩写,让我们选择起来的时候常常望而却步,只好跟着感觉走.所以下面我要介绍的就是那 ...
- 浅谈Java SE、Java EE、Java ME三者的区别
本文把JAVA SE.JAVA EE.JAVA ME拿来做下区别,同时也分享一下作者的一些成果.目前的Java平台根据软件开发人员.服务提供商和设备生产商可以针对特定的市场可以分为三个版本JAVA S ...
- Java SE、Java EE、Java ME 三者区别
现在一个个来分析 1. Java SE(Java Platform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 ...
- Java、Java SE、Java Web和Java EE的区别
刚接触Java对这些概念上的东西有点模糊,查了很多资料,想把它分享出来,要是哪里不对请大家指正(^_^) 1.Java 毫无疑问这就是门语言和C.C++.C#一样没什么好说的. 2.Java SE和J ...
- 24. Java SE 、 Java EE 、JavaME 、 JavaWeb 直接的区别和联系
这个是在别人博客抄的,并不是本人撰写 Java是一门编程语言.Java分为三大版本,SE即标准版,包含了Java核心类库,主要用来开发桌面应用:EE即企业版,包含SE,又有扩展部分(Servlet,J ...
- Java SE、Java EE、Java ME三者的区别
1. Java SE(Java Platform,Standard Edition).Java SE 以前称为 J2SE.它允许开发和部署在桌面.服务器.嵌入式环境和实时环境中使用的 Java 应用程 ...
随机推荐
- datatable删除行之datatable.Rows[i].Delete()。标记之后行没有了
使用Delete()之后行消失了 先在for循环外加上dt.AcceptChanges(); 删除时在dt.AcceptChanges();
- VS2017进程为idXXXX 无法启动解决方案
1.对无法启动项目的 .csproj 后缀文件用记事本打开 找到<WebProjectProperties>xx</WebProjectProperties> 删掉 让后 重新 ...
- 三层+EasyUI+Ajax 提交Form表单
源代码下载:http://download.csdn.net/download/qq_25237531/10267746
- 【JVM】6、聊聊JVM常用参数设置
整体考虑堆大小 -Xms3550m, 初始化堆大小.通常情况和-Xmx大小设置一样,避免虚拟机频繁自动计算后调整堆大小. -Xmx3550m,最大堆大小. 考虑分代设置堆大小 首先通过jstat等工具 ...
- 大型Vuex应用程序的目录结构
译者按: 听前端大佬聊聊Vuex大型项目架构的经验 原文: Large-scale Vuex application structures 译者: Fundebug 为了保证可读性,本文采用意译而非直 ...
- PHP 在WIN10 下配置
apache: https://www.apachehaus.com/ php: https://windows.php.net/ https://windows.php.net/ 集成安装配置版:h ...
- 用Web Services来整合.NET和J2EE
互用性(Interoperability)问题说起来容易但通常实现起来却比较困难.尽管Web service曾承诺要提供最佳的解决方案来衔接基于.NET和J2EE的应用程序,但其过程却并不简单.我们发 ...
- ArcGIS for Server 的修改IP问题
ArcGIS for Server 的修改IP问题 1. [arcgisserver@centos6 ~]$ vi /home/arcgisserver/serverconfig/config ...
- LeanCloud云引擎相关问题
(1).Windows 用户可以在 Github releases 页面 根据操作系统版本下载最新的 32 位 或 64 位 msi 安装包进行安装,安装成功之后在 Windows 命令提示符(或 P ...
- ScrollView与ListView的事件冲突
布局文件 当ListView嵌套在ScrollView中时,会发生冲突,导致ListView控件的拉动效果消失‘ 解决办法: 重写ListView的onTouchEvent(),并在返回前调用getP ...