一、ClassLoader的作用
我们都知道java程序写好以后是以.java(文本文件)的文件存在磁盘上,然后,我们通过(bin/javac.exe)编译命令把.java文件编译成.class文件(字节码文件),并存在磁盘上。但是程序要运行,首先一定要把.class文件加载到JVM内存中才能使用的,我们所讲的classLoader,就是负责把磁盘上的.class文件加载到JVM内存中
二、ClassLoader种类
-
BootStrapClassLoader:C++编写,加载核心库java.*
-
ExtClassLoader:java编程,加载扩展库javax.*
-
AppClassLoader: java编写,加载程序所在的目录
-
自定义ClassLoader:java编写,定制化加载 加载的地方不限,可以是
三、为什么要使用双亲委派机制去加载类
-
避免多份同样字节码的加载
四、jvm内存模型
1.程序计数器:
-
- 当前线程所执行的字节码行号指示器(逻辑)
- 改变计数器的指可以选取下一条需要执行的字节码指令
- 和线程是一对一的关系,“线程私有”
- 对java方法计数,如果是native方法则计数器指为Undefined
- 不会发生内存泄漏
2.java虚拟机栈(Stack)
-
- java方法执行的内存模型
-
-
局部变量表:包含方法执行过程中的所有变量
-
操作数栈:入栈、出栈、复制、交换、产生消费变量
-
-
- 包含多个栈帧
- java方法执行的内存模型
3.本地方法栈:与虚拟机类相似,主要作用于标注了native的方法
5.java堆:对象实例的分配区域,GC的主要区域
五、java内存模型中堆和栈的区别
- 管理方式:栈自动释放,堆需要GC
- 空间大小: 栈比堆小
- 碎片相关: 栈产生的碎片远小于堆
- 分配方式:栈支持动态和静态分配,而堆只支持动态分配
- 效率:栈的效率高于堆
六、可以作为GC ROOT的对象
- 虚拟机栈中的对象(栈帧中的本地变量表)
- 方法区中的常用引用的对象
- 方法区中的类静态属性引用的对象
- 本地方法栈中jni引用的对象
- 活跃线程的引用对象
七、Safepoint
- 分析过程中对象的引用关系不会发生变化的点
- 产生Safepoint的地方:方法调用;循环跳转;异常跳转等
- 安全点数量需要适中
八、垃圾收集器之间的关系
-
Serail收集器(-XX:+UseSerialGC ,复制算法)
- 单线程收集,进行垃圾收集时,必须暂停所有的工作线程
- 简单高效,Client模式下默认的年轻带收集器
-
ParNew收集器(-XX:+UseParNewGC,复制算法)
- 多线程收集,其余的行为、特点和serail收集器一样
- 单核执行效率不如Serail,在多核执行下才有优势
-
Parallel Scavenge收集器(-XX: +UseParallelGC ,复制算法)
- 比起关注用户的线程停顿时间,更关注系统的吞吐量
- 多核模式下才具有优势
- Serial Old收集器(-XX:+UseSerialOldGC, 标记-整理算法)
- 单线程收集,必须暂停所有的工作线程
- 简单高效,Client模式下默认的收集器
- Parallel Old收集器(-XX:UseParallelOldGC, 标记-整理算法)
- 多线程收集,吞吐量优先
- CMS收集器(-XX:UseConcMarkSweepGC, 标记-清除算法)
- 初始标记:
- 并发标记:
- 并发预清理:
- 可中断的并发预清理:
- 最终标记:
- 并发清理:
- 并发重置:
- G1收集器(-XX:+UseG1GC,复制+标记-整理算法)
- 并发和并行的
- 分代收集的
- 空间整合,不会产生内存碎片的问题
- 可预测的停顿
- 将整个java堆内存划分成大小相等的Region,年轻代和老年代不再是物理隔离
九、java内存模型JMM
-
指令重排序的满足条件:在单线程环境下不会影响程序返回的结果、存在数据依赖的不允许进行重排序(无法通过happers-before推导出来的,都可以进行重排序)
-
happers-bofore八大原则:
-
volatile和synchronized的区别:
- 如何保证内存可见性
- 作用对象
- 能够满足的并发问题
- 线程是否阻塞
- 编译器优化
-
cas的缺点:
- ABA问题
- 只能作用与一个共享变量
- 若循环时间长,则会过多消耗cpu,开销大