什么是类加载?
1、我们会有一个共识,就是编写的.java源文件,是编译成.class字节码文件后,才能被JVM所识别的。所以当我们把代码打成jar包或war包,放到机器上部署时,其中也都是.class字节码文件,当机器调用诸如java -jar之类的命令允许我们写好的代码时,实际上就会启动一个JVM进程
2、而每一个.class字节码文件,其实都是一个个我们写好的类,我们如果想要在JVM中运行,肯定是要把这些类加载进来,此时就会有一个概念出现:类加载器。字如其意,类加载器会把我们需要用到的类加载进JVM,供后续代码运行使用
3、类加载是有一定机制的,一般一个类从加载到使用包括如下过程:
加载:当代码中用到这个类时,我们就会去加载。如:带有main()主方法的类、加载过程遇到了其他类、加载的类其父类还没有被加载
验证:校验加载进的.class文件中的内容是否符合JVM规范
准备:给加载进来的类分配内存,并给其中类变量也分配内存空间,赋一个默认值
解析:符号引用替换为直接引用
初始化:诸如static代码块内的赋值逻辑,和类变量的赋值逻辑,会在初始化阶段进行(准备阶段并不会进行我们代码的逻辑赋值,只会给一个默认值)
使用:上述过程都完成后,我们就可以正常的使用该类调用方法,创建对象等
卸载:GC
4、上述类加载过程,肯定是离不开类加载器的,Java中包括:启动类加载器(lib下核心类库)、扩展类加载(lib\ext下类库)器、应用程序类加载器(我们写好的类)、自定义类加载器(自己定义的)
5、类加载器配合双亲委派机制,就可以完整的进行一个类加载过程了。所谓双亲委派机制:先找父类加载器去加载,不行的话,依次向下,由子类加载器加载。如我们编写的类,其继承关系可能也是自己写的类,那么根据双亲委派机制,会追溯到启动类加载器要求加载,但lib内显然是没有我们自己写的类的,然后依次向下,最后会到应用程序类加载器进行加载
6、Tomcat打破了双亲委派机制。Tomcat为每个部署在里面的Web应用都有一个对应的WebApp类加载器,负责加载我们部署的这个Web应用的类。每个WebApp负责加载自己对应的那个Web应用的class文件,也就是我们写好的某个系统打包好的war包中的所有class文件,不会传导给上层类加载器去加载
JVM第1周、第3周作业
JVM调优的本质是什么?
其本质是尽量减少Full GC的次数带给系统性能的影响,而Full GC优化的前提是Minor GC的优化,Minor GC的优化的前提是合理分配内存空间,合理分配内存空间的前提是对系统运行期间的内存使用模型进行预估。
尽量让Minor GC之后的存活对象留在Survivor里不要去老年代,让长期存在的对象尽量早一些到老年代,然后其余的GC参数不做太多优化,系统性能基本上就不会太差(要尽可能让每次Minor GC后存活对象在s区的50%以内)
STW是什么?
STW是Stop The World的缩写,意思是直接停止我们写的Java系统的所有工作线程,让我们写的代码不再运行,然后让垃圾回收线程可以专心致志的进行垃圾回收的工作。在新生代GC时,会发生1次STW,而老年代在使用CMS垃圾回收器时,会发生2次STW
动态年龄判定规则?
如果一次新生代gc过后,发现Survivor区域中的几个年龄的对象加起来超过了Survivor区域的50%,比如说年龄1+年龄2+年龄3的对象大小总和,超过了Survivor区域的50%,此时就会把年龄3以上的对象都放入老年代
JVM执行过程:
查阅可读字节码文件命令:
javap -verbose 类名
日志参数:
-XX:+PrintGCDetails
Java堆参数:
-Xms初始堆大小(必须为1024的倍数,且必须大于1M)
-Xmx最大堆大小(必须为1024的倍数,且必须大于2M,一般和-Xms设置为一样的)
-Xmn新生代大小
栈针内比较重要的部分:
Code:下面的,表示的是操作数栈
局部变量表内的Slot(插槽)顺序(若为静态方法,没有this):
Slot是复用的,若插槽位置判断没有指向了,后续变量的Slot会放在之前的位置上
GC类型:
MinorGC/YoungGC:新生代垃圾收集
MajorGC/OldGC:老年代垃圾收集
FullGC:整个Java堆、方法区垃圾收集
MixedGC:G1独有的GC机制,收集整个新生代和部分老年代
判断对象是不是垃圾:
根据根可达算法,通过一系列名为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则证明此对象是垃圾
判断类是不是垃圾:
JVM中该类的所有实例已经被回收
加载该类的ClassLoader已经被回收
没有任何地方引用该类的Class对象
无法在任何地方通过反射访问这个类
垃圾回收算法:
垃圾回收器
-XX:+UseSerialGC,会开启Serial(新生代)+SerialOld(老年代)的串行收集器组合
-XX:+UseConcMarkSweepGC,会开启ParNew(新生代)+CMS(老年代)的并行收集器组合,Serial Old将作为后备收集器*
-XX:+UseParallelGC,会开启Parallel Scavenge(新生代)+Parallel Old(老年代)的收集器组合
-XX:+UseG1GC,开启G1收集器