当前位置: 首页 > 后端技术 > Java

面试官问我JVM调优,我忍不住了,哈哈哈

时间:2023-04-01 22:04:41 Java

面试官:今天想聊聊JVM调优吗?面试官:您有过在生产环境中调优JVM的经验吗?应聘者:无面试官:……应聘者:嗯……就是这样。我们优化系统的总体思路是这样的。考生:(在这个过程中,需要评估我们建的索引是否合理,是否需要引入分布式缓存,是否需要分库分表等)考生:2.然后,我们会consider是否需要扩展(横向和纵向都考虑)考生:(在这个过程中,我们会怀疑系统压力过大或者系统的硬件能力不足导致系统经常出问题)考生:3.然后,在应用代码层面检查和优化候选人:(扩容不能没完没了,里里外外都有钱。在这个过程中,我们会检查我们写的代码是否存在资源浪费,或者可能存在逻辑上的优化,比如并行处理一些请求)候选:4.接下来在JVM层面检查和优化候选:(查看代码后,我们观察这个过程中JVM是否存在多次GC问题等。)考生:5.最后是网络和操作系统层面的检查考生:(这个过程检查内存/CPU/网络/硬盘读写指标是否正常等)考生:在大多数情况下,第三步结束。JVM和机器上给我们设置的参数已经满足了大部分需求。考生:之前其他团队在“大促”的时候发现了接口处理超时的问题。当时查了各种monitor,怀疑是FULLGC引起的。考生:第一个想法是不调整各种JVM参数进行优化。而是直接加机器考生:(用最粗暴的方法,解决问题最简单,扩展YYDS)面试官:的确考生:不过,学习了JVM相关的调优命令和思路。考生:在我的理解中,调优JVM其实就是在“了解”JVM内存结构和各种垃圾收集器的前提下,结合自己现有的业务,“调整参数”,让你的应用能够正常稳定运行.考生:对于一般的JVM调优,我们认为有几个指标可以参考:“吞吐量”、“暂停时间”和“垃圾收集频率”考生:根据这些指标,我们可能需要调整:考生:1。内存区域大小及相关策略(如整个堆占用多少内存,新生代占用多少,老年代占用多少,Survivor占用多少,老年代提升的条件,etc.)Candidates:例如(-Xmx:设置堆的最大大小Value,-Xms:设置堆的初始值,-Xmn:表示新生代的大小,-XX:SurvivorRatio:Eden区到survivor区等)候选人:(根据经验:IO密集型的可以稍微增加“新生代”空间,因为大部分对象都会在新生代消亡。如果是内存计算密集型,你可以稍微增加“老年代”空间,对象存活时间会更长)candidateCandidate:2.Garbagecollector(选择合适的垃圾收集器,以及各个垃圾收集器的各种调优参数)Candidates:例如(-XX:+UseG1GC:指定JVM使用的垃圾收集器为G1,-XX:MaxGCPauseMillis:设置目标暂停时间,-XX:InitiatingHeapOccupancyPercent:当整个堆内存使用达到一定百分比时,将启动全局并发标记阶段,等)必须了解JVM的各种基础知识,不了解基础怎么谈调优)考生:在大多数场景下,JVM已经能够做到“开箱即用”面试官:的确考生:一般我们都是在“遇到问题”之后进行Tuning,遇到问题之后需要借助各种“工具”来排查考生:1.使用jps命令查看“基本”信息Java进程(进程号,主类)。这个命令非常常用来查看服务器上当前运行了多少个Java进程,它们的进程号以及加载主类的候选者有哪些:2.使用jstat命令查看“统计类”相关信息Java进程(类加载、Compilation相关信息统计、GC概览和各内存区统计)。此命令非常常用来查看GC。考生:3、使用jinfo命令查看和调整Java进程的“运行参数”。考生:4、使用jmap命令查看Java进程的“内存信息”。这个命令很常用来将JVM内存信息转储到一个文件中,然后使用MAT(MemoryAnalyzertool内存分析工具)来分析这个文件。考生:5.通过jstack命令查看JVM“线程信息”。该命令使用常用词排查死锁相关问题候选项:6.还有最近比较流行的Arthas(阿里开源诊断工具),涵盖了上述很多命令的功能,自带图形界面.这也是我这边常用的排查分析工具。采访者:嗯……好吧。之前讲JVM的时候,你也提到在“解释”阶段,将字节码信息解释成机器指令码有两种方式,一种是字节码解释器,另一种是即时编译器(JIT)面试官:请问,你了解JVM的JIT优化技术吗?考生:有两种著名的JIT优化技术:方法内联和逃逸分析。作者:因为每次方法调用都会产生一个栈帧(压栈和出栈记录方法调用位置等)会带来一定的性能损失,所以“方法内联”的优化可以提升一定的性能候选人:在JVM也有相关的参数供我们指定(-XX:MaxFreqInlineSize,-XX:MaxInlineSize)候选者:而“逃逸分析”是一种判断对象是否被外部方法引用或被外部线程访问的分析技术,如果是“不被引用”,可以优化一下,例如:候选:1.锁消除(同步忽略):这个对象只在方法内部被访问,不会被其他地方引用,所以必须是线程安全的,可以把Candidatesforlock相关的代码忽略掉:2.栈分配:对象只会在方法内部被访问,对象直接分配在“栈”中(Java默认在“堆”中分配对象,这需要通过JVM垃圾回收期进行Recycling,需要一定的性能损失,而栈分配要快很多)考生:3.对象的标量替换/分离:当程序真正执行的时候,这个对象并不能被创建,但是它的而是直接创建成员变量。对象拆分后,对象的成员变量可以分配到栈上或者寄存器上,原来的对象不需要分配内存空间这个只能算是参考面试官:我明白了。推荐阅读资料:【美团科技博客】Java中9个常见CMSGC问题分析与解决欢迎关注我的微信公众号【Java3y】聊聊Java面试,在线面试官系列持续更新中!【在线面试官-移动端】系列每周两期持续更新中!【在线面试官-电脑端】系列每周两期持续更新中!原创不易!!求三连!!