共计 2560 个字符,预计需要花费 7 分钟才能阅读完成。
面试官 : 明天要不来聊聊 JVM 调优相干的吧?
面试官 : 你已经在生产环境下有过调优 JVM 的经验吗?
候选者:没有
面试官:…
候选者:嗯…是这样的,咱们个别优化零碎的思路是这样的
候选者:1. 一般来说关系型数据库是先到瓶颈,首先排查是否为数据库的问题
候选者:(这个过程中就须要评估本人建的索引是否正当、是否须要引入分布式缓存、是否须要分库分表等等)
候选者:2. 而后,咱们会思考是否须要扩容(横向和纵向都会思考)
候选者:(这个过程中咱们会狐疑是零碎的压力过大或者是零碎的硬件能力有余导致系统频繁呈现问题)
候选者:3. 接着,利用代码层面上排查并优化
候选者:(扩容是不能无止境的,外头里外都是钱阿。这个过程中咱们会扫视本人写的代码是否存在资源节约的问题,又或者是在逻辑上可存在优化的中央,比如说通过并行的形式解决某些申请)
候选者:4. 再接着,JVM 层面上排查并优化
候选者:(扫视完代码之后,这个过程咱们察看 JVM 是否存在屡次 GC 问题等等)
候选者:5. 最初,网络和操作系统层面排查
候选者:(这个过程查看内存 /CPU/ 网络 / 硬盘读写指标是否失常等等)
候选者:绝大多数状况下,到第三步就完结了,个别通过「运维团队」给咱们设置的 JVM 和机器上的参数,曾经满足绝大多数的需要了。
候选者:之前有过其余团队在「大促」发现接口解决超时的问题,那时候查各种监控狐疑是 FULL GC 导致的
候选者:第一想法不是说去调节各种 JVM 参数来进行优化,而是间接加机器
候选者:(用最粗犷的办法,解决问题是最简略的,扩容 YYDS)
面试官:的确
候选者:不过,我是学过 JVM 相干的调优命令和思路的。
候选者:在我的了解下,调优 JVM 其实就是在「了解」JVM 内存构造以及各种垃圾收集器前提下,联合本人的现有的业务来「调整参数」,使本人的利用可能失常稳固运行。
候选者:个别调优 JVM 咱们认为会有几种指标能够参考:『吞吐量』、『进展工夫』和『垃圾回收频率』
候选者:基于这些指标,咱们就有可能须要调整:
候选者:1. 内存区域大小以及相干策略(比方整块堆内存占多少、新生代占多少、老年代占多少、Survivor 占多少、降职老年代的条件等等)
候选者:比方(-Xmx:设置堆的最大值、-Xms:设置堆的初始值、-Xmn:示意年老代的大小、-XX:SurvivorRatio:伊甸区和幸存区的比例等等)
候选者:(按教训来说:IO 密集型的能够略微把「年老代」空间加大些,因为大多数对象都是在年老代就会灭亡。内存计算密集型的能够略微把「老年代」空间加大些,对象存活工夫会更长些)
候选者:2. 垃圾回收器(抉择适合的垃圾回收器,以及各个垃圾回收器的各种调优参数)
候选者:比方(-XX:+UseG1GC:指定 JVM 应用的垃圾回收器为 G1、-XX:MaxGCPauseMillis:设置指标进展工夫、-XX:InitiatingHeapOccupancyPercent:当整个堆内存应用达到肯定比例,全局并发标记阶段 就会被启动等等)
候选者:没错,这些都是就地取材,具体问题具体分析(前提是得懂 JVM 的各种基础知识,基础知识都不懂,谈何调优)
候选者:在大多数场景下,JVM 曾经可能达到「开箱即用」
面试官:的确
候选者:个别咱们是「遇到问题」之后才进行调优的,而遇到问题后须要利用各种的「工具」进行排查
候选者:1. 通过 jps 命令查看 Java 过程「根底」信息(过程号、主类)。这个命令很罕用的就是用来看以后服务器有多少 Java 过程在运行,它们的过程号和加载主类是啥
候选者:2. 通过 jstat 命令查看 Java 过程「统计类」相干的信息(类加载、编译相干信息统计,各个内存区域 GC 详情和统计)。这个命令很罕用于看 GC 的状况
候选者:3. 通过 jinfo 命令来查看和调整 Java 过程的「运行参数」。
候选者 :4. 通过 jmap 命令来查看 Java 过程的「内存信息」。这个命令很罕用于把 JVM 内存信息 dump 到文件,而后再用 MAT(Memory Analyzer tool 内存解析工具) 把文件进行剖析
候选者:5. 通过 jstack 命令来查看 JVM「线程信息」。这个命令用常用语排查死锁相干的问题
候选者:6. 还有近期比拟热门的 Arthas(阿里开源的诊断工具),涵盖了下面很多命令的性能且自带图形化界面。这也是我这边罕用的排查和剖析工具
面试官:嗯…好吧。之前聊 JVM 的时候,你也提到过在「解释」阶段,会有两种形式把字节码信息解释成机器指令码,一个是字节码解释器、一个是即时编译器(JIT)
面试官 : 我想问问,你理解 JVM 的 JIT 优化技术嘛?
候选者:JIT 优化技术比拟闻名的有两种:办法内联和逃逸剖析
候选者:所谓办法内联就是把「指标办法」的代码复制到「调用的办法」中,防止产生实在的办法调用
候选者:因为每次办法调用都会生成栈帧(压栈出栈记录办法调用地位等等)会带来肯定的性能损耗,所以「办法内联」的优化能够进步肯定的性能
候选者:在 JVM 中也有相干的参数给予咱们指定(-XX:MaxFreqInlineSize、-XX:MaxInlineSize)
候选者:而「逃逸剖析」则是判断一个对象是否被内部办法援用或内部线程拜访的剖析技术,如果「没有被援用」,就能够对其进行优化,比如说:
候选者:1. 锁打消(同步疏忽):该对象只在办法外部被拜访,不会被别的中央援用,那么就肯定是线程平安的,能够把锁相干的代码给疏忽掉
候选者:2. 栈上调配:该对象只会在办法外部被拜访,间接将对象调配在「栈」中(Java 默认是将对象调配在「堆」中,是须要通过 JVM 垃圾回收期进行回收,须要损耗肯定的性能,而栈内调配则快很多)
候选者:3. 标量替换 / 拆散对象:当程序真正执行的时候能够不创立这个对象,而间接创立它的成员变量来代替。将对象拆分后,能够调配对象的成员变量在栈或寄存器上,本来的对象就无需分配内存空间了
候选者:不过扯了这么多,不同的 JVM 版本对 JIT 的优化都不太雷同(:这里也只能算是一个参考
面试官:懂了。
倡议浏览材料:【美团技术博客】Java 中 9 种常见的 CMS GC 问题剖析与解决
欢送关注我的微信公众号【Java3y】来聊聊 Java 面试,对线面试官系列继续更新中!
【对线面试官 - 挪动端】系列 一周两篇继续更新中!
【对线面试官 - 电脑端】系列 一周两篇继续更新中!
原创不易!!求三连!!