学习的前提,升级版本的2019年的jvm视频学完,GC,jvm监控与调优学完,tomcat和微服务优化。
文章目录
类装载器:装载什么?有哪些?双亲委派机制?沙箱安全机制?
体系结构图中:灰色不存在垃圾回收,线程私有。亮色,线程共享,存在垃圾回收
java8删除了持久代,用元空间代替了。
官方修改的动机是:oracle收购了另外两家虚拟机之后,整合了他们的成果,删掉了持久代,用元空间代替。
gc作用在方法区和堆。
有对象引用加个一,没对象引用就是0,会被回收。
复制之后有交换,谁空谁是to!
标记清除法:避免了空间浪费,但是产生了内存碎片。
标记压缩/标记整理算法:没有了内存碎片,但是要移动对象,性能低,耗时比较长。
没有完美的算法,根据代的特性选择算法,所谓的分代收集算法。
什么是垃圾
没有引用指向某个对象了,慢慢的这个对象就会被回收。内存中不再被使用到的空间就是垃圾。
要进行垃圾回收,如何判断一个对象可以被回收
引用计数法如下:
另外一种方法就是GC root 来判断一个对象是否应该被回收:根搜索路径算法
上图中从根部进行遍历,能到达的对象,如通过对象B到达B1,B2,称为对象可达。对象c,到不了,则成为对象不可达。
来看一个case:
gc root 就类似linux的根节点。这种对象就叫做gc root 对象(GC roots 是一个对象的集合,是很多对象)。然后开始遍历扫描,能被扫描到的称为引用可达对象。没有被扫描到的,就是引用不可达对象,哪怕他们彼此间存在循环引用问题,也是引用不可达的对象,解决了引用计数法不能处理循环引用的弊端。
哪些对象可以入选为gc roots集合呢?
代码演示:
这个题目答:根节点的可达性分析+什么是gc root。
jvm的参数类型
jvm的参数有三种,分别是:标配,x参数,xx参数。其中xx参数是重点。
标配参数
标配参数是从jdk1.0到jdk12.0都在的参数,叫做标配参数。
X参数
分别是xint解释执行,Xcomp编译执行,Xmixed先编译再执行。
case案例
先来解决一个问题,再使用某个参数之前要先判断他的状态,也就是下面这个问题:
常用jps(查看java的后台进程)和jinfo(查看正在运行进程的各种信息)去解决上面这个问题。
让HelloGC这个类打印一句话,然后睡眠。用jps -l指令查看正在运行的java线程。就得到了hellogc的进程号13632.
jinfo查看某个java线程是否开启了某个参数:以是否打印gc收集细节为例
前面是“-”,说明并没有开启打印gc细节信息。
然后尝试将该功能打开:-XX:+PrintGCDetails
再次查看是否被激活:利用jinfo
如图所示,已经被激活了。类似的还有是否启用串行垃圾回收器:
案例:设置元空间大小和晋升老年代的年龄
使用上面的jinfo -flag 关键字 线程号的方法查看元空间的大小:
可以看出来jvm设置的元空间的初始值只有21M左右。
使用vm options 设置元空间的大小:
再次查看,确定设置是否生效:
同样的方法,确定一下新生代升级到老年区的对象年龄是不是15:
确实是15.
jinfo案例一:查看初始的堆大小
jinfo案例2:用flags查看所有的jvm参数
初始化加载之后,系统会帮你做:Non-default vm flags
command line:是人为的参数,我们的vpoptions只配置了MetaspaceSize,其他都是自带的。
jinfo案例3:查看bool型和kv型参数的配置
坑题
配置的时候如下图:Xms,Xmx既没有+也没有=,也就是说哪类也不算。
实际上是XX参数中kv参数的略写:
查看jvm默认值第二种方法:
查看出厂默认的参数
把公式展开:
case案例:
如果要做jvm调优,这个命令十分重要: java -XX:+printFlagsInitial.这个命令用于查看jvm初始化的参数。
在不启动任何java程序的情况下,可以看到一i额全局的参数,如上图所示。
查看改过的参数
公式:
打印的内容跟上面的出厂默认值界面差不多,但是有的是=有的是:=,我们改过的参数就是“:=”来显示。
启动时带参数执行,联系spring boot的jar包的启动方式!
修改元空间的大小为512M。
然后查看前后打印出来元空间大小的内容,确实发生了变化,证明我们的设置生效了。
这就是运行java命令的同时,打印出参数,并且修改某些参数的具体办法。
-XX:+PrintCommandLineFlags:打印命令行参数。
这种命令的使用,打印的是常用参数,有:初始堆大小,最大堆大小,打印命令行参数(打开)等等。比较重要的可以看到是使用并行的垃圾回收器(java8默认)。垃圾回收算法,到jdk1.8有4种,但是垃圾回收器有7种。这个命令主要是看最后一个参数。