Jvm:
一、类加载器分类
- 引导类加载器:BootStrapClassLoader(出于安全考虑,Bootstrap启动类加载器只加载包名为java、javax、sun等开头的类)
- 自定义类加载器:Extension ClassLoader AppClassLoader (Tomcat也自定义了类加载器)
双亲委派机制
1、避免类的重复加载,
避免类的重复加载(一旦有类的模式被加载了,就不会委托他的子类进行加载,避免类的重复加载)向上委托找父类
2、防止核心api被篡
比如说我们编写一个String类
二、JVM构成部分、作用
1. 程序计数器:
2. 虚拟机栈/java方法栈:
一个线程是一个虚拟机栈,线程每执行一个方法生成一个栈帧
每个线程在创建时都会创建一个虚拟机栈,虚拟机栈内会保存一个个的栈帧,每个栈帧对应一个方法.
3. 本地方法栈:
与java方法栈类似,线程是私有的,也会出现OOM、SOF。
4. 方法区:
5. 堆区:
堆区是JVM中非常重要的一个区域,JVM中规定所有的对象和数组都应该存放在堆中,对象的引用地址
存入虚拟机栈中的栈帧中。当方法执行完后,所创建的对象并不会收回,而是要等JVM后台执行GC后,对象才会收回
- 堆区流程详解:
创建的对象会存储在eden(伊甸区),有不断的对象创建过来,如果这时eden存储满了,
这时触发YongGC/MInor GC,找到我们eden区的垃圾对象进行回收掉, 如果不是垃圾对象(回收不掉堆)放到S0区(并且记录GC(进行垃圾回收次数)次数)
这时S0区可能回收掉一部分,将无法回收掉的(此时还不是垃圾对象的)放到S1区,并且累加GC次数。S0跳到S1,S1跳到S0,如果GC次数达到15次还未被回收掉,则直接放到老年代。
则可以看出新生代存放的是一些新对象或者说很快会被回收掉的,老年代则存放常驻的对象(如果创建的对象过大(eden/s0无法存放),可能会直接存放到老年代区域)
找到JVM中(主要是堆中)有哪些垃圾对象,有两种方式:
- 引用计数法:实现简单,计数器为0 则表示垃圾对象(被引用次数),缺点:需要额外的时间/空间来维护,并且无法处理两个对象循环引用的问题。
- 可达性分析法:
垃圾回收算法:
标记-清除法/复制算法/标记整理法
对象进行了移动,就需要修改栈帧中的引用地址