【JAVA进阶架构师指南】之五:JVM性能调优
前言
首先给大家说声对不起,最近属实太忙了,白天上班,晚上加班,回家还要收拾家里,基本每天做完所有事儿都是凌晨一两点了,没有精力再搞其他的了.
好了,进入正题,让我们来聊聊JVM篇最后一个章节----JVM性能调优.童鞋们随便打开一个大厂的招聘岗位JD,应该都会有JVM调优相关的描述,其实招聘方不一定要求候选人真的对JVM调优有实际调优经验,但是至少得有思路,知道应该怎样进行JVM层面的性能调优,说实话,知道如何进行JVM层面的性能调优的人,在面试中确实是有加分的.
笔者在公司担任面试官的时候,经常会看到候选人简历描述有JVM性能调优经验,每当这个时候我都会问候选人一个问题,你是如何进行JVM性能调优的,很多童鞋的回答就是:噢,就是调整一下初始堆大小,新生代大小.这明显不是笔者想要的答案,因为这根本就不叫JVM性能调优.童鞋们对号入座一下,对JVM调优仅仅是我上述说的那样的,赶紧改一下简历,不要说自己会JVM性能调优.说实话,对JVM进行性能调优是对架构师的要求,甚至我敢说很多架构师都不一定有实际的JVM性能调优经验.话不多说,让我们进入正题,我们将从以下几点来讲解如何进行性能调优:
- JVM性能调优的前提
- JVM性能调优的预备知识
- STW现象--Stop-The-World
- 垃圾回收器的种类
- 性能调优的目的
- 如何进行性能调优
JVM性能调优的前提
所有有经验的架构师一定会有一个共识,JVM层面的性能调优一定是作为最后的调优手段,在此之前,一定要确保系统其它方面都已经做到了极致,无法再进行调优了,在这个前提下,才会考虑JVM性能调优.这里的其他方面包括从前端到架构到代码层面,我举一些例子
从浏览器/APP角度可进行的优化有:
- 减少HTTP请求次数.
- 使用客户端缓存.
- 浏览器启用压缩
- 使用CDN加速
- 动态资源和静态资源分离
从系统层面可进行的优化有:
- 启用缓存,比如redis缓存数据
- 使用集群
- 异步处理,比如引入消息队列
- 对代码的优化
以上列出的每一点,都能单独拎出来讲很久,但是博文篇幅问题,就不细说了,有兴趣的童鞋可以自行下去了解,我们只着重说一下代码优化,相信大家都知道,业界比较公认的编码规范是阿里巴巴发布的<java开发手册>,里面的内容都是阿里集团多年来血的教训积累的精华,阿里集团内部有一个组织专门负责手册的编写和推广,并且在不断进行优化,最新版发布到泰山版了(我看的时候还是华山版,哈哈).如果有童鞋还不知道的,我建议去下载下来看一看.另外阿里云上有<java开发手册>的考试,如果通过了这个考试,说明你的编码规范还是不错的,有兴趣的童鞋可以去试一下.
除此之外,童鞋们还应该了解JVM本身为我们悄悄做的各种优化,其中最重要的是JIT编译器的优化.我举几个例子,比如:方法内联,逃逸分析等.默认情况下,这些都是开启的,如果不开启这些功能,JVM性能会下降50%以上.除此之外,还有一些比如:栈上分配,TLAB等优化.这些内容由于平时我们开发中不会用到,是JVM在背后悄悄为我们做了优化,因此可能很多童鞋都不知道,但是如果想成为一个合格的架构师,这些内容都是必须要知道的,毕竟架构师的知识广度和深度决定了架构师的高度.
除此之外,性能调优一定是基于性能测试的,空口说进行性能调优的都是耍流氓,只有在经过了实际的性能测试后,我们才知道系统的瓶颈在哪里,才知道那些方面需要进行调优,如何进行调优.常用的性能测试指标有TPS/QPS/吞吐量.并且默认所有的接口访问都遵循二八原则(接口每天80%的访问量集中在20%的时间内).
JVM性能调优的预备知识
在进行JVM性能调优之前,我们还得了解JVM,比如我前面的几篇有关JVM的博文,都是需要掌握的,比如JVM内存模型,垃圾回收机制等等.另外我们还需要掌握一些进行JVM分析的工具.其实在我们安装JDK的时候,JDK已经为我们准备了许多有用的性能调优监控工具,我们可以看一下JDK安装目录下的bin目录:

- jps: 主要用来输出JVM中运行的进程状态信息
- jstack: 主要用来查看某个Java进程内的线程堆栈信息
- jmap: 用来查看堆内存使用状况,一般结合jhat使用
- jstat: JVM统计监测工具
- jconsole: 图形化的统计工具
- jvisualvm: 比jconsole功能更强的图形化的监控工具
另外我们需要知道,当JVM发生OOM异常时,可以使用命令生成一个.hprof后缀的dump文件,该文件是某个时间节点的heap的快照,我们可以使用VisualVM来查看,也可以用第三方提供的一些工具,比如eclipse的MAT来查看内存溢出的原因.
STW现象
所谓STW现象(Stop-The-World)是指在执行垃圾收集算法时,Java应用程序的其他所有线程(除了垃圾收集线程之外的线程)都被挂起.此时,系统只允许GC线程继续运行,其他线程全部暂停,等待GC线程执行完毕后才能继续执行.这些工作都是由虚拟机在后台自动发起和自动完成的,是在用户不可见的情况下把用户正常工作的线程全部停掉,举个例子,某个接口平时可能只需要50ms的RT,忽然某次调用花费了200ms.因此STW对实时性要求很高的系统来说是难以接受的.
垃圾回收器的种类
既然有STW现象,那么有没有解决方案呢?这就是我们接下来要讲的,垃圾回收器的种类,目前为止,JVM一共为我们提供了七种垃圾回收器,其中年轻代有三种,老年代有三种,另外还有一种特殊的G1:



当然,在更新版本的JDK中还有一种ZGC,为未来垃圾回收器提供了一种趋势,有兴趣的童鞋可以自行了解.
性能调优的目的和具体过程
有了前面的铺垫,终于来到了我们最重要的正题:如何进行JVM性能调优?在我看来JVM调优的具体步骤分为如下几步:
- 确定调优的目的,选择合适的GC collector
- 调整JVM heap的大小
- 调整young generation在整个JVM heap中所占的比重.
确定调优的目的,选择合适的GC collector
由于每种垃圾回收器的特性并不相同,因此我们需要根据我们的调优目的选择合适的垃圾回收器,比如,我们需要降低STW的停顿时间,那我们就不能选用串行和并行的垃圾回收器,而应该选用并发的垃圾回收器,即CMS,与之搭配的新生代垃圾回收器就应该选用ParNew.目前一般主流互联网公司都是用CMS垃圾回收器.
调整JVM heap的大小
确定了垃圾回收器的类型,就需要调整JVM heap的大小,在这一步的时候,首先我们需要了解JVM相关的一些指令,比如可以在启动java程序时加上
-XX:+HeapDumpOnOutOfMemoryError,当发生OOM时,JVM会自动为我们生成DUMP文件
-XX:+PrintGCDetails -Xloggc:D:\gclogger\gc.log -XX:+PrintGCDateStamps 生成GC日志
-Xms2g -Xmx2g 当然,还应该要根据实际情况设置heap的最大最小值,童鞋们要知道,默认情况下,java程序启动的最小heap大小为1/64物理内存,最大值为1/4物理内存,一般要求我们最大最小值保持一致,避免JVM频繁扩容和缩容导致不必要的性能浪费.
调整young generation在整个JVM heap中所占的比重.
确定了heap的大小,还需要确定新生代的比重
–Xmn1500m -XX:MetaspaceSize=150M
当然,再厉害的架构师也不可能一次就调整得出最佳的JVM配置参数,而是应该多设置几组不同的值,放到生产环境(或者和生产环境一样的环境,比如阿里内部有预发环境,和生产环境保持一致)进行性能测试,通过对比结果得出最佳的JVM性能调优参数,完成JVM性能调优.
总结
读完了本篇文章,我相信童鞋们应该或多或少会有些收获.掌握JVM调整的核心步骤:
- 确定调优的目的,选择合适的GC collector
- 调整JVM heap的大小
- 调整young generation在整个JVM heap中所占的比重.
不了解如何进行JVM的调优的人,把本文内容好好理解后,能让面试官刮目相看;了解JVM调优,但是条理不清晰的童鞋,可能会对JVM调优有更清晰的认识.总而言之,笔者认为本文是一篇满满的干货,网上许多讲JVM调优的博文,并没有这么系统的讲解过真正应该如何进行JVM调优.当然笔者能力有限,如文章有错误,欢迎指正,毕竟是人就会犯错.
PS:一入JVM深似海,从此再也出不来.对JVM有兴趣的童鞋,可以钻研,但是在经验不足之前,不建议太过深入了解JVM,否则会耽误自己.当然,立志要成为一名牛逼的架构师,这些都是必须要会的.
本文我们讲完了JVM,下一篇开始,让我们继续学习JAVA锁相关的内容.
如果觉得博主写的不错,欢迎关注博主微信公众号,博主会不定期分享技术干货!

本文由博客一文多发平台 OpenWrite 发布!
【JAVA进阶架构师指南】之五:JVM性能调优的更多相关文章
- Java架构师面试题——JVM性能调优
JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对 ...
- 【JAVA进阶架构师指南】之四:垃圾回收GC
前言 在[JAVA进阶架构师指南]系列二和三中,我们了解了JVM的内存模型以及类加载机制,其中在内存模型中,我们说到,从线程角度来说,JVM分为线程私有的区域(虚拟机栈/本地方法栈/程序计数器)和 ...
- 【JAVA进阶架构师指南】之二:JVM篇
前言 谈到JAVA,就不得不提JVM---JAVA程序员绕不开的话题.也许有童鞋会说,我不懂JVM,但是我一样可以写出JAVA代码,我相信说这种话的童鞋,往往是只有1-3年的初级开发人员,对JAV ...
- 【JAVA进阶架构师指南】之一:如何进行架构设计
前言 本博客是长篇系列博客,旨在帮助想提升自己,突破技术瓶颈,但又苦于不知道如何进行系统学习从而提升自己的童鞋.笔者假设读者具有3-5年开发经验,java基础扎实,想突破自己的技术瓶颈,成为一位优 ...
- 【JAVA进阶架构师指南】之三:深入了解类加载机制
前言 在上一篇文章中,我们知道了JVM的内存划分,其中在说到方法区的时候说到方法区中存放的信息包括[已被JVM加载的类信息,常量,静态变量,即时编译的代码等],整个方法区其实就和类加载有关. 类加 ...
- Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述
概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解
摘要: JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望 ...
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解(转VIII)
JVM本身就是一个java进程,一个java程序运行在一个jvm进程中.多个java程序同时运行就会有多个jvm进程.一个jvm进程有多个线程至少有一个gc线程和一个用户线程. JDK本身提供了很多方 ...
- JVM 性能调优实战之:一次系统性能瓶颈的寻找过程
玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次…JVM 的性能优化被认为是底层优化,门槛较高, ...
随机推荐
- oracle的操作-表空间
查询以创建的表空间 select dbms_metadata.get_ddl('TABLESPACE','你的表空间名称') from dual; --查询空间创建的位置 select t1.name ...
- Apache 慢连接dos
http://neue.v2ex.com/t/108717------不实用 http://www.blogjava.net/bukebushuo/articles/293776.html http: ...
- 解决删除~/Library/Caches/CocoaPods/search_index.json重新pod search还是不起作用
今天新苹果机安装cocoapods,安装完以后发现怎么pod search 都没有用 命令行提示: swhcxp@iosdevmac ~ % pod search Almofire Setup com ...
- HTML5移动端最新兼容问题解决方案
1.安卓浏览器看背景图片,有些设备会模糊.用同等比例的图片在PC机上很清楚,但是手机上很模糊,原因是什么呢?经过研究,是devicePixelRatio作怪,因为手机分辨率太小,如果按照分辨率来显示网 ...
- 程序员都在用的 IDEA 插件(不断更新)
IDEA一些不错的插件分享 目录 IDEA一些不错的插件分享 插件集合 CamelCase Translation LiveEdit MarkDown Navigator Jrebel CheckSt ...
- ATX插件机制-学习学习
添加插件:记录一下 https://testerhome.com/topics/16074 webview操作: https://testerhome.com/topics/12599
- JSP+SSM+Mysql实现的图书馆预约占座管理系统
项目简介 项目来源于:https://gitee.com/gepanjiang/LibrarySeats 因原gitee仓库无数据库文件且存在水印,经过本人修改,现将该仓库重新上传至个人gitee仓库 ...
- [JavaWeb基础] 010.Struts2 下载文件
在web开发中,我们经常会有文件的上传下载功能,上一篇的介绍中我们讲解了上传功能,那么这次我们来讲讲下载功能. 1.首先我们需要有一个用于处理下载的测试页面,也就是jsp. <body> ...
- bootstrap table Showing 1 to 5 of 5 rows 页码显示英文
注意导包先后顺序bootstrap-table-zh-CN.js链接:https://cdn.bootcdn.net/ajax/libs/bootstrap-table/1.16.0/locale/b ...
- python常见面试题讲解(十)数字颠倒
题目描述 描述: 输入一个整数,将这个整数以字符串的形式逆序输出 程序不考虑负数的情况,若数字含有0,则逆序形式也含有0,如输入为100,则输出为001 输入描述: 输入一个int整数 输出描述: 将 ...