学习的前提,升级版本的2019年的jvm视频学完,GC,jvm监控与调优学完,tomcat和微服务优化。

JVM·GC快速回顾复习

14.互联网大厂高频面试题-JVMGC·上_其他
14.互联网大厂高频面试题-JVMGC·上_其他_02
14.互联网大厂高频面试题-JVMGC·上_其他_03
类装载器:装载什么?有哪些?双亲委派机制?沙箱安全机制?
体系结构图中:灰色不存在垃圾回收,线程私有。亮色,线程共享,存在垃圾回收
14.互联网大厂高频面试题-JVMGC·上_其他_04
java8删除了持久代,用元空间代替了。
14.互联网大厂高频面试题-JVMGC·上_java_05
官方修改的动机是:oracle收购了另外两家虚拟机之后,整合了他们的成果,删掉了持久代,用元空间代替。
14.互联网大厂高频面试题-JVMGC·上_其他_06
gc作用在方法区和堆。
14.互联网大厂高频面试题-JVMGC·上_其他_07
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_08
有对象引用加个一,没对象引用就是0,会被回收。
14.互联网大厂高频面试题-JVMGC·上_java_09
复制之后有交换,谁空谁是to!
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_10
标记清除法:避免了空间浪费,但是产生了内存碎片。
14.互联网大厂高频面试题-JVMGC·上_其他_11
标记压缩/标记整理算法:没有了内存碎片,但是要移动对象,性能低,耗时比较长。
没有完美的算法,根据代的特性选择算法,所谓的分代收集算法。

谈谈你对GC Roots的理解

14.互联网大厂高频面试题-JVMGC·上_java_12

什么是垃圾

14.互联网大厂高频面试题-JVMGC·上_垃圾回收_13
14.互联网大厂高频面试题-JVMGC·上_java_14
没有引用指向某个对象了,慢慢的这个对象就会被回收。内存中不再被使用到的空间就是垃圾。

要进行垃圾回收,如何判断一个对象可以被回收

14.互联网大厂高频面试题-JVMGC·上_默认值_15
14.互联网大厂高频面试题-JVMGC·上_默认值_16
引用计数法如下:
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_17
14.互联网大厂高频面试题-JVMGC·上_默认值_18
另外一种方法就是GC root 来判断一个对象是否应该被回收:根搜索路径算法
14.互联网大厂高频面试题-JVMGC·上_默认值_19
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_20
上图中从根部进行遍历,能到达的对象,如通过对象B到达B1,B2,称为对象可达。对象c,到不了,则成为对象不可达。
14.互联网大厂高频面试题-JVMGC·上_其他_21
来看一个case:
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_22
gc root 就类似linux的根节点。这种对象就叫做gc root 对象(GC roots 是一个对象的集合,是很多对象)。然后开始遍历扫描,能被扫描到的称为引用可达对象。没有被扫描到的,就是引用不可达对象,哪怕他们彼此间存在循环引用问题,也是引用不可达的对象,解决了引用计数法不能处理循环引用的弊端。
哪些对象可以入选为gc roots集合呢?
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_23
代码演示:
14.互联网大厂高频面试题-JVMGC·上_其他_24
这个题目答:根节点的可达性分析+什么是gc root。

JVM的标配参数和X参数

14.互联网大厂高频面试题-JVMGC·上_默认值_25
14.互联网大厂高频面试题-JVMGC·上_默认值_26

jvm的参数类型

14.互联网大厂高频面试题-JVMGC·上_垃圾回收_27
jvm的参数有三种,分别是:标配,x参数,xx参数。其中xx参数是重点。

标配参数

标配参数是从jdk1.0到jdk12.0都在的参数,叫做标配参数。
14.互联网大厂高频面试题-JVMGC·上_java_28
14.互联网大厂高频面试题-JVMGC·上_默认值_29

X参数

14.互联网大厂高频面试题-JVMGC·上_默认值_30
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_31
分别是xint解释执行,Xcomp编译执行,Xmixed先编译再执行。

XX参数之布尔类型

14.互联网大厂高频面试题-JVMGC·上_java_32
14.互联网大厂高频面试题-JVMGC·上_其他_33

case案例

14.互联网大厂高频面试题-JVMGC·上_垃圾回收_34
先来解决一个问题,再使用某个参数之前要先判断他的状态,也就是下面这个问题:
14.互联网大厂高频面试题-JVMGC·上_其他_35
常用jps(查看java的后台进程)和jinfo(查看正在运行进程的各种信息)去解决上面这个问题。
14.互联网大厂高频面试题-JVMGC·上_java_36
让HelloGC这个类打印一句话,然后睡眠。用jps -l指令查看正在运行的java线程。就得到了hellogc的进程号13632.
jinfo查看某个java线程是否开启了某个参数:以是否打印gc收集细节为例
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_37
前面是“-”,说明并没有开启打印gc细节信息。

然后尝试将该功能打开:-XX:+PrintGCDetails
14.互联网大厂高频面试题-JVMGC·上_java_38
再次查看是否被激活:利用jinfo
14.互联网大厂高频面试题-JVMGC·上_java_3914.互联网大厂高频面试题-JVMGC·上_java_40

如图所示,已经被激活了。类似的还有是否启用串行垃圾回收器:
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_41

XX参数的KV设值类型

14.互联网大厂高频面试题-JVMGC·上_垃圾回收_42

14.互联网大厂高频面试题-JVMGC·上_默认值_43

案例:设置元空间大小和晋升老年代的年龄
14.互联网大厂高频面试题-JVMGC·上_其他_44
使用上面的jinfo -flag 关键字 线程号的方法查看元空间的大小:
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_45
可以看出来jvm设置的元空间的初始值只有21M左右。
使用vm options 设置元空间的大小:
14.互联网大厂高频面试题-JVMGC·上_默认值_46
再次查看,确定设置是否生效:
14.互联网大厂高频面试题-JVMGC·上_java_47
同样的方法,确定一下新生代升级到老年区的对象年龄是不是15:
14.互联网大厂高频面试题-JVMGC·上_其他_48
确实是15.

XX参数之XmsXmx坑题

14.互联网大厂高频面试题-JVMGC·上_默认值_49
jinfo案例一:查看初始的堆大小
14.互联网大厂高频面试题-JVMGC·上_java_50
jinfo案例2:用flags查看所有的jvm参数
14.互联网大厂高频面试题-JVMGC·上_默认值_51
14.互联网大厂高频面试题-JVMGC·上_默认值_52
初始化加载之后,系统会帮你做:Non-default vm flags
14.互联网大厂高频面试题-JVMGC·上_java_53
command line:是人为的参数,我们的vpoptions只配置了MetaspaceSize,其他都是自带的。
14.互联网大厂高频面试题-JVMGC·上_其他_54
jinfo案例3:查看bool型和kv型参数的配置
14.互联网大厂高频面试题-JVMGC·上_java_55

坑题

14.互联网大厂高频面试题-JVMGC·上_其他_56
配置的时候如下图:Xms,Xmx既没有+也没有=,也就是说哪类也不算。
14.互联网大厂高频面试题-JVMGC·上_其他_57
实际上是XX参数中kv参数的略写:
14.互联网大厂高频面试题-JVMGC·上_其他_58

JVM盘查家底查看初始默认值

14.互联网大厂高频面试题-JVMGC·上_java_59

查看jvm默认值第二种方法:
14.互联网大厂高频面试题-JVMGC·上_垃圾回收_60

查看出厂默认的参数

14.互联网大厂高频面试题-JVMGC·上_垃圾回收_61
把公式展开:
14.互联网大厂高频面试题-JVMGC·上_java_62
case案例:
14.互联网大厂高频面试题-JVMGC·上_其他_63
如果要做jvm调优,这个命令十分重要: java -XX:+printFlagsInitial.这个命令用于查看jvm初始化的参数。
在不启动任何java程序的情况下,可以看到一i额全局的参数,如上图所示。

查看改过的参数

14.互联网大厂高频面试题-JVMGC·上_垃圾回收_64
公式:
14.互联网大厂高频面试题-JVMGC·上_其他_65
打印的内容跟上面的出厂默认值界面差不多,但是有的是=有的是:=,我们改过的参数就是“:=”来显示。
14.互联网大厂高频面试题-JVMGC·上_其他_66

JVM盘查家底查看修改变更值

启动时带参数执行,联系spring boot的jar包的启动方式!
14.互联网大厂高频面试题-JVMGC·上_java_67
修改元空间的大小为512M。
然后查看前后打印出来元空间大小的内容,确实发生了变化,证明我们的设置生效了。
14.互联网大厂高频面试题-JVMGC·上_java_68
这就是运行java命令的同时,打印出参数,并且修改某些参数的具体办法。
14.互联网大厂高频面试题-JVMGC·上_其他_69
-XX:+PrintCommandLineFlags:打印命令行参数。
14.互联网大厂高频面试题-JVMGC·上_默认值_70
这种命令的使用,打印的是常用参数,有:初始堆大小,最大堆大小,打印命令行参数(打开)等等。比较重要的可以看到是使用并行的垃圾回收器(java8默认)。垃圾回收算法,到jdk1.8有4种,但是垃圾回收器有7种。这个命令主要是看最后一个参数。