一、jvm结构:
- PC寄存器器:
a. 每个线程拥有⼀一个pc寄存器器;
b. 指向下⼀一条指令的地址 - 方法区:
a. 保存装载的类的元信息:类型的常量量池,字段、⽅方法信息,⽅方法字节码;
jdk6时,String等常量信息置于⽅法区,jdk7移到了堆中;
b. 通常和永久区(Perm)关联在⼀一起 - 堆:
a. 应⽤用系统对象都保存在java堆中;
b. 所有线程共享java堆;
c. 对分代GC来说,堆也是分代的; - 栈:
- a. 线程私有;
- b. 栈由⼀一系列列帧组成(因此java栈也叫做帧栈);
- c. 帧保存⼀一个⽅方法的局部变量量(局部变量量表)、操作数栈、常量量池指针;
- d. 每⼀一次⽅方法调⽤用创建⼀一个帧,并压栈。
二、jvm内存模型:
- 每⼀一个线程有⼀一个⼯工作内存,和主存独⽴立;
- ⼯工作内存存放主存中变量量的值的拷⻉贝;
- 对于普通变量量,⼀一个线程中更更新的值,不不能⻢马上反应在其他变量量中;如果需要在其他线程中⽴立即可⻅见,需要使⽤用volatile关键字;
- volatile不不能代替锁,⼀一般认为volatile⽐比锁性能好(不不绝对),使⽤用volatile的条件是语义是否满⾜足应⽤用;
- 可⻅见性:⼀一个线程修改了了变量量,其他线程可以⽴立即知道。
- a. volatile;
- b. synchronized(unlock之前,写变量量值回主存);
- c. final(⼀一旦初始化完成,其他线程可⻅见)。
三、java四引⽤用:
1. 强引⽤用:
强引⽤用是使⽤用最普遍的引⽤用。如果⼀一个对象具有强引⽤用,那垃圾回收器器绝不不会回收它。当内存空间不不⾜足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终⽌止,也不不会靠随意回收具有强引⽤用的对象来解决内存不不⾜足的问题。
2. 软引⽤用:
如果内存空间不不⾜足了了,就会回收这些对象的内存。只要垃圾回收器器没有回收它,软引⽤用可以和⼀一个引⽤用队列列
(ReferenceQueue)联合使⽤用,如果软引⽤用所引⽤用的对象被垃圾回收器器回收,Java虚拟机就会把这个软引⽤用加⼊入到与之关联的引⽤用队列列中。
3. 弱引⽤用:
弱引⽤用与软引⽤用的区别在于:只具有弱引⽤用的对象拥有更更短暂的⽣生命周期。在垃圾回收器器线程扫描它所管辖的内存区域的过程中,⼀一旦发现了了只具有弱引⽤用的对象,不不管当前内存空间⾜足够与否,都会回收它的内存。
弱引⽤用可以和⼀一个引⽤用队列列(ReferenceQueue)联合使⽤用,如果弱引⽤用所引⽤用的对象被垃圾回收,Java虚拟机就会把这个弱引⽤用加⼊入到与之关联的引⽤用队列列中。
4. 虚引⽤用:
虚引⽤用在任何时候都可能被垃圾回收器器回收,主要⽤用来跟踪对象被垃圾回收器器回收的活动,被回收时会收到⼀一个系统通知。虚引⽤用与软引⽤用和弱引⽤用的⼀一个区别在于:虚引⽤用必须和引⽤用队列列 (ReferenceQueue)联合使⽤用。当垃圾回收器器准备回收⼀一个对象时,如果发现它还有虚引⽤用,就会在回收对象的内存之前,把这个虚引⽤用加⼊入到与之关联的引⽤用队列列中。
四、GC算法分类:
1. 引⽤用计数法(没有被java采⽤用):
a. 原理理:对于⼀一个对象A,只要有任何⼀一个对象引⽤用了了A,则A的引⽤用计数器器就加1,当引⽤用失效时,引⽤用计数器器就减1,只要对象A的引⽤用计数器器的值为0,则对象A就会被回收。
b. 问题:
i. 引⽤用和去引⽤用伴随加法和减法,影响性能;
ii. 很难处理理循环引⽤用。
2. 标记清除法:
a. 原理理:现代垃圾回收算法的思想基础。标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段。⼀一种可⾏行行的实现是,在标记节点,⾸首先通过根节点,标记所有从根节点开始的可达对象。因此,未被标记的对象就是未被引⽤用的垃圾对象。然后在清除阶段,清除所有未被标记的对象。
b. 问题:
i. 标记和清除两个过程效率不不⾼高,产⽣生内存碎⽚片导致需要分配较⼤大对象时⽆无法找到⾜足够的连续内存⽽而需要触发⼀一次GC操作。
3. 标记压缩法:
a. 原理理:适合⽤用于存活对象较多的场合,如⽼老老年年代。它在标记-清除算法的基础上做了了⼀一些优化。标记阶段⼀一样,但之后,将所有存活对象压缩到内存的⼀一端。之后,清除边界外所有的空间。
b. 优点:
i. 解决了了标记- 清除算法导致的内存碎⽚片问题和在存活率较⾼高时复制算法效率低的问题。
4. 复制算法:
a. 原理理:将原有的内存空间分为两块,每次只使⽤用其中⼀一块,在垃圾回收时,将正在使⽤用的内存中的存活对象复制到未使⽤用的内存块中,之后清除正在使⽤用的内存块中的所有对象,交换两个内存的⻆角⾊色,完成垃圾回收。
b. 问题:
i. 不不适⽤用于存活对象⽐比较多的场合,如⽼老老年年代。
5. 分代回收法:
a. 原理理:根据对象存活周期的不不同将内存划分为⼏几块,⼀一般是新⽣生代和⽼老老年年代,新⽣生代基本采⽤用复制算法,⽼老老年年代采⽤用标记整理理算法。
五、MinorGC & FullGC:
1. Minor GC通常发⽣生在新⽣生代的Eden区,在这个区的对象⽣生存期短,往往发⽣生GC的频率较⾼高,回收速度⽐比较快,⼀一般采⽤用复制-回收算法。
2. Full GC/Major GC 发⽣生在⽼老老年年代,⼀一般情况下,触发⽼老老年年代GC的时候不不会触发Minor GC,所采⽤用的是标记-清除算法。
六、垃圾收集器器:
1. Serial New收集器器是针对新⽣生代的收集器器,采⽤用的是复制算法;
2. Parallel New(并⾏行行)收集器器,新⽣生代采⽤用复制算法,⽼老老年年代采⽤用标记整理理;
3. Parallel Scavenge(并⾏行行)收集器器,针对新⽣生代,采⽤用复制收集算法;
4. Serial Old(串串⾏行行)收集器器,新⽣生代采⽤用复制,⽼老老年年代采⽤用标记清理理;
5. Parallel Old(并⾏行行)收集器器,针对⽼老老年年代,标记整理理;
6. CMS收集器器,基于标记清理理;
7. G1收集器器(JDK):整体上是基于标记清理理,局部采⽤用复制;
综上:新⽣生代基本采⽤用复制算法,⽼老老年年代采⽤用标记整理理算法。cms采⽤用标记清理理;
七、java类加载机制:
1. 概念:虚拟机把描述类的数据⽂文件(字节码)加载到内存,并对数据进⾏行行验证、准备、解析以及类初始化,最终形成可以被虚拟机直接使⽤用的java类型(java.lang.Class对象)。
2. 类⽣生命周期:
类加载过程:读取⼆二进制字节流到jvm—>验证格式语义等—>为静态变量量分配内存空间—>常量量池引⽤用解析—>执⾏行行static标识的代码
a. 加载过程:通过⼀一个类的全限定名来获取定义此类的⼆二进制字节流,将这个字节流所代表的静态存储结构转化为⽅方法区的运⾏行行时数据结构。在内存中(⽅方法区)⽣生成⼀一个代表这个类的java.lang.Class对象,作为⽅方法区这个类的各种数据的访问⼊入⼝口;
b. 验证过程:为了了确保Class⽂文件的字节流中包含的信息符合当前虚拟机的要求,⽂文件格式验证、元数据验证、字节码验证、符号引⽤用验证;
c. 准备过程:正式为类属性分配内存并设置类属性初始值的阶段,这些内存都将在⽅方法区中进⾏行行分配;
准备阶段,static对象会被设置默认值,static final对象会被赋上给予的值。
d. 解析阶段:虚拟机将常量量池内的符号引⽤用替换为直接引⽤用的过程。
i. 符号引⽤用:字符串串,引⽤用对象不不⼀一定被加载;
ii. 直接引⽤用:指针或者地址偏移量量,引⽤用对象⼀一定在内存中。
e. 初始化阶段:类初始化阶段是类加载过程的最后⼀一步。初始化阶段就是执⾏行行类构造器器<clint>()⽅方法的过程。
f. 使⽤用阶段:
g. 卸载阶段: