JVM:
全文参考:https://blog.csdn.net/darkness0604/category_9840308.html(这套jvm博文与MCA一致)
JDK、JRE、JVM
浅谈JDK、JRE、JVM区别与联系_Αиcíеиτеǎг的博客-CSDN博客_jdk jre jvm 的区别和联系(浅谈JDK、JRE、JVM区别与联系)
简单的可以理解为一种包含关系,从JDK的目录结构就可以看出来
jvm是一种规范,虚构出来的一台机器,最常见的实现是HotSpot;
JVM虚拟机种类_will way的博客-CSDN博客_jvm虚拟机类型(JVM的多种实现)
类的生命周期
java文件运行图:
clas的声明周期
JVM第三天-Class三大生命周期之Class加载原理_darkness0604的博客-CSDN博客(Class三大生命周期之Class加载原理)
loading的双亲委派机制
三大声明周期之Linking和Initializing
1,linking过程的resolution解析的理解:
符号引用的理解_人间风流逍遥客的博客-CSDN博客_符号引用
https://www.iteye.com/blog/denverj-1242056
为类、接口、方法、成员变量的符号引用定位直接引用(如果符号引用先到常量池中寻找符号,再找先应的类型,无疑会耗费更多时间),完成内存结构的布局。
总结笔记
类加载-初始化
加载过程
Loading
双亲委派,主要出于安全来考虑
LazyLoading 五种情况
–new getstatic putstatic invokestatic指令,访问final变量除外
–java.lang.reflect对类进行反射调用时
–初始化子类的时候,父类首先初始化
–虚拟机启动时,被执行的主类必须初始化
–动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化
ClassLoader的源码
findInCache -> parent.loadClass -> findClass()
自定义类加载器
extends ClassLoader
overwrite findClass() -> defineClass(byte[] -> Class clazz)
加密
第一节课遗留问题:parent是如何指定的,打破双亲委派,学生问题桌面图片
用super(parent)指定
双亲委派的打破
如何打破:重写loadClass()
何时打破过?
JDK1.2之前,自定义ClassLoader都必须重写loadClass()
ThreadContextClassLoader可以实现基础类调用实现类代码,通过thread.setContextClassLoader指定
热启动,热部署
osgi tomcat 都有自己的模块指定classloader(可以加载同一类库的不同版本)
混合执行 编译执行 解释执行
检测热点代码:-XX:CompileThreshold = 10000
Linking
Verification
验证文件是否符合JVM规定
Preparation
静态成员变量赋默认值
Resolution
将类、方法、属性等符号引用解析为直接引用 常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用
Initializing
调用类初始化代码 <clinit>,给静态成员变量赋初始值
小总结:
load - 默认值 - 初始值
new - 申请内存 - 默认值 - 初始值
GC中判断垃圾的两种算法:
1,引用计数法
它的做法是为每个对象添加一个引用计数器,用来统计指向该对象的引用个数。一旦某个对象的引用计数器为0,则说明该对象已经死亡,便可以被回收了。引用计数法还有一个重大的漏洞:无法处理循环引用。
2,根可达算法
这种算法的思路在于:将一系列被称为GC Roots的变量作为初始的存活对象合集,然后从该合集出发,所有能够被该集合引用到的对象,并将其加入到该集合中,而不能被该合集所引用到的对象,并可对其宣告死亡。
什么是GC ROOT:
- 虚拟机栈(栈帧中的本地变量表)中引用的对象;
- 本地方法区中的静态属性引用对象;
- 方法区中的常量引用对象;
- 本地方法栈中的JNI(Native方法)的引用对象;
常见的垃圾清除算法
1. 标记清除(mark sweep) - 位置不连续 产生碎片 效率偏低(两遍扫描)
2. 拷贝算法 (copying) - 没有碎片,浪费空间
3. 标记压缩(mark compact) - 没有碎片,效率偏低(两遍扫描,指针需要调整)标记-清除算法:标记无用对象,然后进行清除回收。缺点:效率不高,无法清除垃圾碎片。
复制算法:按照容量划分二个大小相等的内存区域,当一块用完的时候将活着的对象复制到另一块上,然后再把已使用的内存空间一次清理掉。缺点:内存使用率不高,只有原来的一半。
标记-整理算法:标记无用对象,让所有存活的对象都向一端移动,然后直接清除掉端边界以外的内存。
分代算法:根据对象存活周期的不同将内存划分为几块,一般是新生代和老年代,新生代基本采用复制算法,老年代采用标记整理算法。