JVM基础篇1 - Class的加载
JVM基础篇2 - 指令集
JVM进阶篇1 - 内存模型
JVM进阶篇2 - GC垃圾回收
JVM总览- JVM架构
引入jvm面试题:
- 谈谈对jvm的理解?java8虚拟机和之前的变化更新?
- 什么是OOM,什么是栈溢出StackOverFlowError ?怎么分析
- JVM常用的调优参数有哪些?
- 内存快照如何抓取?怎么分析Dump文件?知道吗?
- 谈谈jVM,类加载器的认识?
1. 什么是JVM?
jvm是一种规范,只识别class文件
最常用的java虚拟机 :Hotspot
java解释和编译模式混合:执行次数特别多的代码会做成及时编译,本地编译,下次调用不需要通过解释器(解释器+热点代码编译)
简单的JVM调优:
配置解释或编译方式: Idea->run->edit Configuration->VM options
- 默认为混合方式
- -Xint (纯解释)
- -Xcomp (纯编译,加载慢,执行快)
判定热点数据 -XX:CompileThreshold = 10000
2. class文件时是怎样加载进内存的?
- loding :将class文件load进内存,双亲委派机制
- linking :
- verification 校验 文件是否符合class文件的标准 ca fe ba be 开头
- preoaration 为静态变量赋默认值(如 0 )
- resolution 解析 将class中的常量池的引用转为具体的内存地址
- initializing 静态变量的赋值,调用静态代码块,类初始化代码
3. 什么是 ClassLoader?
使用 boostrap 类(c++的模块)加载器输出类加载器为 null
双亲委派机制: 向上委托,向下加载
类加载的过程:
从上图中我们就更容易理解了,当一个Hello.class这样的文件要被加载时。不考虑我们自定义类加载器,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。如果没有,那么会拿到父加载器,然后调用父加载器的loadClass方法。父类中同理也会先检查自己是否已经加载过,如果没有再往上。注意这个类似递归的过程,直到到达Bootstrap classLoader之前,都是在检查是否加载过,并不会选择自己去加载。直到BootstrapClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。那么有人就有下面这种疑问了?
为什么要设计这种机制?
这种设计有个好处是,如果有人想替换系统级别的类:String.java。篡改它的实现,在这种机制下这些系统的类已经被Bootstrap classLoader加载过了(为什么?因为当一个类需要加载的时候,最先去尝试加载的就是BootstrapClassLoader),所以其他类加载器并没有机会再去加载,从一定程度上防止了危险代码的植入。
检查自己能否加载类调用findClass方法
findClass 的设计模式 : 钩子函数,模板方法(也就是在父类中定义好了方法,子类只需重写父类的部分方法即可 )
自定义classLoader : 重写findClass方法
4. Java8大原子操作:
- lock(锁定):作用于主内存,它把一个变量标记为一条线程独占状态;
- read(读取):作用于主内存,它把变量值从主内存传送到线程的工作内存中,以便随后的load动作使用;
- load(载入):作用于工作内存,它把read操作的值放入工作内存中的变量副本中;
- use(使用):作用于工作内存,它把工作内存中的值传递给执行引擎,每当虚拟机遇到一个需要使用这个变量的指令时候,将会执行这个动作;
- assign(赋值):作用于工作内存,它把从执行引擎获取的值赋值给工作内存中的变量,每当虚拟机遇到一个给变量赋值的指令时候,执行该操作;
- store(存储):作用于工作内存,它把工作内存中的一个变量传送给主内存中,以备随后的write操作使用;
- write(写入):作用于主内存,它把store传送值放到主内存中的变量中。
- unlock(解锁):作用于主内存,它将一个处于锁定状态的变量释放出来,释放后的变量才能够被其他线程锁定;