前言

  首先给大家说声对不起,最近属实太忙了,白天上班,晚上加班,回家还要收拾家里,基本每天做完所有事儿都是凌晨一两点了,没有精力再搞其他的了.

  好了,进入正题,让我们来聊聊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性能调优的更多相关文章

  1. Java架构师面试题——JVM性能调优

    JVM内存调优 对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数. 1.Full GC 会对整个堆进行整理,包括Young.Tenured和Perm.Full GC因为需要对 ...

  2. 【JAVA进阶架构师指南】之四:垃圾回收GC

    前言   在[JAVA进阶架构师指南]系列二和三中,我们了解了JVM的内存模型以及类加载机制,其中在内存模型中,我们说到,从线程角度来说,JVM分为线程私有的区域(虚拟机栈/本地方法栈/程序计数器)和 ...

  3. 【JAVA进阶架构师指南】之二:JVM篇

    前言   谈到JAVA,就不得不提JVM---JAVA程序员绕不开的话题.也许有童鞋会说,我不懂JVM,但是我一样可以写出JAVA代码,我相信说这种话的童鞋,往往是只有1-3年的初级开发人员,对JAV ...

  4. 【JAVA进阶架构师指南】之一:如何进行架构设计

    前言   本博客是长篇系列博客,旨在帮助想提升自己,突破技术瓶颈,但又苦于不知道如何进行系统学习从而提升自己的童鞋.笔者假设读者具有3-5年开发经验,java基础扎实,想突破自己的技术瓶颈,成为一位优 ...

  5. 【JAVA进阶架构师指南】之三:深入了解类加载机制

    前言   在上一篇文章中,我们知道了JVM的内存划分,其中在说到方法区的时候说到方法区中存放的信息包括[已被JVM加载的类信息,常量,静态变量,即时编译的代码等],整个方法区其实就和类加载有关. 类加 ...

  6. Java性能优化权威指南-读书笔记(二)-JVM性能调优-概述

    概述:JVM性能调优没有一个非常固定的设置,比如堆大小设置多少,老年代设置多少.而是要根据实际的应用程序的系统需求,实际的活跃内存等确定.正文: JVM调优工作流程 整个调优过程是不断重复的一个迭代, ...

  7. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解

    摘要: JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat.hprof等小巧的工具,本博客希望 ...

  8. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解(转VIII)

    JVM本身就是一个java进程,一个java程序运行在一个jvm进程中.多个java程序同时运行就会有多个jvm进程.一个jvm进程有多个线程至少有一个gc线程和一个用户线程. JDK本身提供了很多方 ...

  9. JVM 性能调优实战之:一次系统性能瓶颈的寻找过程

    玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次…JVM 的性能优化被认为是底层优化,门槛较高, ...

随机推荐

  1. linux常用命令---yum 工具

    yum 工具 yum工具是红帽子才有的软件管理工具,例如suse乌班图等系统,没有yum,apt-get apt-install

  2. python之pytest框架实现

    一.pytest测试框架简介: pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点: 简单灵活,容易上手 支持参数化 能够支持简单的单元测试和复杂的功能测试,还可以用来做se ...

  3. MySQL慢查询优化(线上案例调优)

    文章说明 这篇文章主要是记录自己最近在真实工作中遇到的慢查询的案例,然后进行调优分析的过程,欢迎大家一起讨论调优经验.(以下出现的表名,列名都是化名,实际数据也进行过一点微调.) PS:最近做了一个面 ...

  4. VMware 11安装Mac OS X 10.10 (转载)

    VM11安装Mac OS X 10.10 工具/原料 1.VMware Workstation 112.unlocker 203(for OS X 插件补丁)3.Mac OS X 10.10镜像方法/ ...

  5. xampp apache 安全性问题

    要禁止 Apache 显示目录结构列表,只需将 Option 中的 Indexes 去掉即可.<Directory "D:/Apa/blabla"> Options I ...

  6. 【scrapy运行姿势】scrapy.cmdline.execute

    scrapy.cmdline.execute scrapy的cmdline命令 1.启动爬虫的命令为:scrapy crawl (爬虫名) 2.还可以通过以下方式来启动爬虫 方法一:创建一个.py文件 ...

  7. Socket - TCP编程

    Socket是网络编程的一个抽象概念. 通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协议类型即可 socket参数及常用功能 ...

  8. SpringCloud(一)- SpringCloud简介

    唯能极于情,故能极于剑 有问题或错误请及时联系小编或关注小编公众号 “CodeCow”,小编一定及时回复和改正,期待和大家一起学习交流 一.SpringCloud 1.1.Cloud 是什么 ?: 官 ...

  9. 剑指Offer之旋转数组的最小数字

    题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转 ...

  10. CSS基础选择器总结

    基础选择器 作用 特点 使用情况 用法 标签选择器 可以选出所有相同的标签,比如p 不能差异化选择 较多 p {color:red;} 类选择器 可以选出1个或多个标签 可以根据需求选择 非常多 .n ...