young1lin
2021-01-15 09:40:23 +08:00
大多数情况下,人家只要你了解基本的 JVM 知识,其实只是要你看过《深入理解 Java 虚拟机》这本书就够了。
一般 JVM 内存结构(这部分一般是可以看哪里导致的 OOM,进而知道如何解决,比如我两年前接手的老项目经常报 PermGen OutOfMemoryError,就是因为 1.6,1.7 版本的 JDK 永久代分配的内存太少了);
一些基本的启动参数调优(关闭偏向锁,Xms 和 Xmx 根据机器大小,设置成 60%-75% 之间的相等的值,避免大量内存碎片产生等等)
垃圾回收算法(什么代用什么回收算法,为什么要这么用。例如大对象直接进入老年代,是因为 young 区采用的复制清除算法);
什么时候进行回收,是什么 GC ;
查看 dump 文件分析哪段 Java 程序导致内存一直占用很高或者频繁 Full GC 导致 CPU 使用率飙升(一般这个用开源的工具);
几种引用(像 ThreadLocal 里面就用到了 WeakReference );
会 javap -verbose 反编译查看具体 class 的虚拟机指令( invokespecial 之类的),这部分是 Class 文件结构那部分的(一般这个是用来装逼的,或者像 Hikari cp 一样说我这反编译后都比其他的少了几条指令呢,还不高效?);
使用基本 JDK 自带的工具,例如 jstack,jps,jconsole,jmap 等等(我就用过 jstack + top + ps aux 等命令找到具体使 CPU 飙升的堆栈信息,然后改那个 bug );
双亲委派机制(让你知道 ClassLoader 相关的内容,进而知道 static 变量在同一 ClassLoader 加载的时候才是唯一的,而不是 JVM 进程内唯一,后者说法不是特别严谨);
编译到执行过程(什么抽象语法树啊,注解什么时候加进来的之类的),还有编译到运行期间的各种优化( String 类型合并,锁消除,逃逸分析之类的);
理解了这些,差不多了我觉得,比如你在 debug 的时候,点那个 drop frame 就知道什么能跳回之前的方法了,因为 Java 的方法调用就是压栈(虚拟机栈)。
如果你还想了解更多,看《 Java 虚拟机规范》。
如果还不够,你再看看《自己动手写 Java 虚拟机》这个来装逼,你可以按照书上来写个,然后放到你自己的 Github 上,和面试官说,这是我写的 Java 虚拟机,关于 JVM 的还有什么要问的吗?
后面两本书,说实话我没看,没必要,最后的故事转自一个美团的面试的人的,那个美团的一个小组组长说看看人家,自己写了个虚拟机,真牛啊(窃喜,这本书没什么人了解)。