建网站服务器是什么东西,wordpress媒体库无法显示,第八章 电子商务网站建设试题,做外贸的物流网站全文共 1890 个字#xff0c;读完大约需要 6 分钟。 上一篇我们讲了垃圾标记的一些实现细节和经典算法#xff0c;而本文将系统的讲解一下垃圾回收的经典算法#xff0c;和Hotspot虚拟机执行垃圾回收的一些实现细节#xff0c;比如安全点和安全区域等。
因为各个平台的虚拟… 全文共 1890 个字读完大约需要 6 分钟。 上一篇我们讲了垃圾标记的一些实现细节和经典算法而本文将系统的讲解一下垃圾回收的经典算法和Hotspot虚拟机执行垃圾回收的一些实现细节比如安全点和安全区域等。
因为各个平台的虚拟机操作内存的方法各不相同且牵扯大量的程序实现细节所以本文不会过多的讨论算法的具体实现只会介绍几种算法思想及发展过程。
垃圾回收算法
1、标记-清除算法
标记-清除算法是最基础的算法像它的名字一样算法分为“标记”和“清除”两个阶段首先需要标记出所需要回收的对象标记完成后统一收集被标记的对象。
优点 实现简单。 缺点 产生不连续的内存碎片“标记”和“清除”的执行效率都不高。
标记-清除算法执行过程图 本文图片来自《深入理解Java虚拟机》
2、复制算法
复制算法就是将内存分为大小相同的两块当这一块使用完了就把当前存活的对象复制到另一块然后一次性清空当前区块。
优点 执行效率高。
缺点 空间利用率低 因为复制算法每次只能使用一半的内存。 3、标记-整理算法
也称标记-压缩算法标记-整理算法采用和标记清除算法一样的对象“标记”但后续不会对可回收对象进行清理而是将存活的对象往一端空闲空间移动然后清理边界以外的内存空间。
优点 解决了内存碎片问题比复制算法空间利用率高。
缺点 因为有局部对象移动相对效率不高。
标记-整理算法执行过程图 4、分代收集算法
目前商用虚拟机都采用的是分代收集的算法这种算法按照对象存活周期把内存分为几块一般Java中分为新生代和老年代。把存活率低的对象分到新生代使用复制算法提高垃圾回收的性能老年代则存放存活率搞的对象使用标记-清除和标记-整理的算法提高内存空间使用率。
新生代和老生代的具体介绍和参数配置后续的文章会详细讲解。
垃圾回收执行细节
本节将详细的介绍一下HotSpot虚拟机在执行垃圾回收时的一些细节目的是让读者更好的理解Java虚拟机。
HotSpot虚拟机 它是Sun JDK和OpenJDK自定的虚拟机也是目前使用最广泛的虚拟机。
垃圾回收流程 Java虚拟机在内存回收之前为了保证内存的一致性必须先暂停程序的执行也就是传说中的Stop The World简称STW在使用可达性分析算法枚举GC Roots标记出死亡对象再进行垃圾回收。
垃圾回收遇到的问题 那既然是要暂停程序的运行就一定要保证停止的时间足够短并且可控不然带来的灾难将是毁灭性的。
解决方案 显然HotSpot在设计的时候也考虑到了这个问题所以在JIT编译的时候就会使用OopMap数据结构来记录栈和寄存器上的引用这样虚拟机就直接知道了那些地方存放着对象的引用如下图为我编译String.hashCode()方法的部分本地代码 可以看出使用OopMap数据结构存储了普通对象的指针引用。
查看汇编的方法启动命令窗体执行java -XX:UnlockDiagnosticVMOptions -XX:PrintAssembly YouTestClass
命令可能会报错 Could not load hsdis-amd64.dll; library not loadable; PrintAssembly is disabled
报错解决方法使用编译好的hsdis.dll放到jre安装目录\bin\server目录下即可hsdis.dll地址地址https://pan.baidu.com/s/1-D6u0gnUx291LXS3bHOorA
安全点Safepoint
在OopMap的协助下HotSpot可以快速的完成GC Roots枚举但导致OopMap内容变化的指令很多而且如果给每个对象生成对应的OopMap会造成大量额外的空间这会导致GC成本很高所以HotSpot只会在“特定的位置”生成对应的OopMap这些位置就成为“安全点”。
HotSpot也并不是任何时刻都会停顿下来进行GC只会在程序都到底安全点之后才会GC所以安全点的设置不能太少让GC等待时间太长也不能太多增大运行时的成本。
安全点的两种线程中断方式
抢断式中断不需要线程的执行代码去主动配合当发生GC时先强制中断所有线程然后如果发现某些线程未处于安全点恢复程序运行直到进入安全点为止。
主动式中断不强制中断线程只是简单地设置一个中断标记各个线程在执行时轮询这个标记一旦发现标记被改变(出现中断标记)时那么将运行到安全点后自己中断挂起。目前所有商用虚拟机全部采用主动式中断。
安全区域Saferegion
安全点机制仅仅是保证了程序执行时不需要太长时间就可以进入一个安全点进行 GC 动作但是当特殊情况时比如线程休眠、线程阻塞等状态的情况下显然HotSpot不可能一直等待被阻塞或休眠的线程正常唤醒执行此时就引入了安全区的概念。
安全区(Saferegion)安全区域是指在一段区域内对象引用关系等不会发生变化在此区域内任意位置开始GC都是安全的线程运行时首先标记自己进入了安全区然后在这段区域内如果线程发生了阻塞、休眠等操作HotSpot发起GC时将忽略这些处于安全区的线程。当线程再次被唤醒时首先他会检查是否完成了GC Roots枚举(或这个GC过程)如果完成了就继续执行否则将继续等待直到收到可以安全离开的Safe Region的信号为止。
参考
《深入理解Java虚拟机》
《垃圾回收的算法与实现》
最后
关注公众号发送“gc”关键字领取《垃圾回收的算法与实现》学习资料。