8适配器模式
8适配器模式
8适配器模式
7装饰器模式
6桥接模式
5代理模式
4原型模式
3建造者模式
2工厂模式
1单例模式
问题:无法处理循环引用,额外空间存储计数器,频繁更新操作
从GC Roots集合开始遍历,标记被引用到的对象,加入该集合,这个过程成为标记。未被标记即可回收。
漏报,可达对象未被标记,可能造成JVM崩溃(STW解决)
误报,不可达标记为可达,影响小,失去回收机会
JVM收到Stop-the-world请求,等待所有的线程都到达安全点,才允许GC线程进行独占的工作。
停止非GC线程,直到GC完成,造成GC pause(垃圾回收暂停时间)
安全点的初始目的是找到稳定的执行状态,JVM堆栈不会发生变化,保证垃圾回收器安全执行可达性分析
要保证在可接受性能和内存开销内避免机器码长时间进入安全点,间接减少GC暂停时间
解释执行,JVM可控,有安全点请求时,执行一条字节码便进行一次安全点检测。
即时编译,cpu执行机器码jVM不可控,生成机器码时插入安全点
解决了碎片化问题,但内存利用率极低
JVM中的垃圾回收器采用可达性分析来探索所有存活的对象。
它从GC Roots集合出发,探索标记引用对象。
为了防止在标记过程中堆栈的状态发生改变,采取安全点机制来实现Stop-the-world,暂停其他非垃圾回收线程。
回收三种方式
大部分对象存活一小段时间,存活下来的小部分会存活很长一段时间
针对对象存活时间特性将堆划分为新生代和老生代,存活时间够长的新生代移动到老生代。
新老代采用不同回收算法
新生代频繁使用耗时短垃圾回收算法回收(Minor GC)
老生代对象在空间不足时,JVM全堆扫描,耗时也不记成本了
根据新对象生产速率采用动态分配策略,调整Eden和Survivor比例
Survivor占比大空间浪费高
老年代和新生代的比例 -XX:NewRatio=value 默认2, 新生代:老生代 1:2
也可直接指定新生代内存大小 -XX:NewSize=value
eden survivor大小按比例设置 -XX:SurvivorRatio=value ,若是8 则单个survivor:eden 1:8, 一个survivor占整个新生代的1/10
Thread Local Allocation Buffer 虚拟机参数 -XX:+UseTLAB,默认开启
线程向JVM申请一段连续的内存作为私有的TLAB,后续分配空闲先从TLAB分配,不足在申请新TLAB
Eden空间不足,开启Minor GC收集新生代垃圾,存活的Eden和from复制到to再交换from,to的指针(下次回收时to指向还是空survivor)
将堆划分为一个个512字节的卡,并且维护卡表来存储每张卡的标识位。标识位代表对应卡是否可能存在指向新生代对象的引用。
将卡表中的脏卡中的对象加入MinorGC的GC Root列表,而不用扫描老生代,扫描完成后将表示为清零。
堆分为新生代和老年代,不同代采用不同的垃圾回收算法。
新生代分为Eden区和两个大小一致的Survivor区,其中一个是空的。
新生代Minor GC中,Eden区和非空Survivor区的存活对象会被复制到空的Survivor区中,当 Survivor区中的存活对象复制次数超过一定数值时,晋升至老年代。、
Minor GC只针对新生代垃圾回收,所以在枚举GC Roots时候,老年代到新生代的引用。为了避免扫描整个老年代,引入了名为卡表的技术,大致地标出可能存在老年代到新生代引用的内存区域。
10Java对象的内存布局