jvm内存模型分析-垃圾收集算法

硅谷探秘者 1448 0 0

1.标记-清除算法

        最基础的收集算法是“标记-清除”(Mark-Sweep)算法,如同它的名字一样,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,它的标记过程其实在前一节讲述对象标记判定时已经介绍过了。之所以说它是最基础的收集算法,是因为后续的收集算法都是基于这种思路并对其不足进行改进而得到的。它的主要不足有两个:一个是效率问题,标记和清除两个过程的效率都不高;另个是空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。

2.复制算法

        为了解决效率间题,种称为“复制”( Copying)的收集算法出现了,它将可用内存按容量划分为大小相等的两块,每次只使用其中的块a当这块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。这样使得每次都是对整个半区进行内存回收,内存分配时也就不用考虑内存碎片等复杂情况,只要移动堆顶指针,按顺序分配内存即可实现简单,运行高效。只是这种算法的代价是将内存缩小为了原来的一半,未免太高了一点。

        现在的商业虚拟机都采用这种收集算法来回收新生代,BM公司的专门研究表明,新生代中的对象98%是朝生夕死”的,所以并不需要按照1:1的比例来划分内存空间,而是将内存分为一块较大的den空间和两块较小的 Survivor空间,每次使用Eden和其中块 Survivor°…当回收时,将Eden和 Survivor中还存活着的对象一次性地复制到另外一块Survivor空间上,最后清理掉Eden和刚才用过的 Survivor空间。 Hotspot虚拟机默认Eder和 Survivor的大小比例是8:1,也就是每次新生代中可用内存空间为整个新生代容量的90%(80%+10%),只有10%的内存会被“浪费”当然,98%的对象可回收只是般场景下的数据,我们没有办法保证每次回收都只有不多于10%的对象存活,当 Survivor空间不够用时,需要依赖其他内存(这里指老年代)进行分配担保( Handle promotion)内存的分配担保就好比我们去银行借款,如果我们信誉很好,在98%的情况下都能按时偿还,于是银行咡能会默认我们下一次也能按时按量地偿还贷款,只需要有一个担保人能保证如果我不能还款时,可以从他的账户扣钱,那银行就认为没有风险了。内存的分配担保也一样,如果另外一块 Survivor空间没有足够空间存放上一次新生代收集下来的存活对象时,这些对象将直接通过分配担保机制进入老年代。关于对新生代进行分配担保的内容,在本章稍后在讲解垃圾收集器执行规则时还会再详细讲解。

3.标记-整理算法

        复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。根据老年代的特点,有人提出了另外一种“标记-整理”( Mark-Compact)算法,标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。

4.分代收集算法

        当前商业虚拟机的垃圾收集都采用“分代收集”( Generational Collection)算法,这种算法并没有什么新的思想,只是根据对象存活周期的不同将内存划分为几一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记一清理”或者“标记一整理”算法来进行回收。

内容摘自《深入理解java虚拟机》


评论区
请写下您的评论...
暂无评论...
猜你喜欢
java虚拟机(jvm) 1599 jvm-器和配策略(1)说起(GarbagcCollcction,GC),大部人都把这项技术当做java语言的伴生产物。事实上,GC的历史比Java久远,1960
java虚拟机(jvm) 4768 jvm(1)已经对进行了一个宏观的概括http://www.jiajiajia.club/weblog/blog/artical/82那么下边具体一下方执行的过程还是以一个
java虚拟机(jvm) 3574 jvm(5)堆溢出以及1.拟堆溢出代码packagetest;importjava.util.ArrayList;importjava.util.List
java虚拟机(jvm) 3028 jvm(1)Java虚拟机在执行Java程序的过程中会把它所管理的为若干个不同的数据区域jvm包括三大子系统:类加载子系统,运行时数据区(结构),执行引擎详细图示
java虚拟机(jvm) 6005 Jvm-class文件结构以下面的类为例介绍一下class文件的结构packagejvm;publicclassMainTest{publicstaticinta=0
java虚拟机(jvm) 3917 (StackFrame)用于储局部变量表、操作数栈、动态链接、方出口等信息。局部变量表是一组变量值储空间,用于放方参数和方部定义的局部变量。在Java程序被编译为Class文件时,就在方的Code属性
java虚拟机(jvm) 2464 这里以HotSpot为例,且所说的对象指普通的Java对象,不包括数组和Class对象等。参考资料深入理解java虚拟机《周志明》1.对象的布局HotSpot虚拟机中,对象在储的布局可以
java虚拟机(jvm) 5768 块称为“类加载器”。类加载器可以说是Java语言的一项创新,也是Java语言流行的重要原因之一,它最初是为了满足JavaApPlet的需求而开发出来的。虽然目前JavaApplet技术基本上已经“死掉
归档
2018-11  12 2018-12  33 2019-01  28 2019-02  28 2019-03  32 2019-04  27 2019-05  33 2019-06  6 2019-07  12 2019-08  12 2019-09  21 2019-10  8 2019-11  15 2019-12  25 2020-01  9 2020-02  5 2020-03  16 2020-04  4 2020-06  1 2020-07  7 2020-08  13 2020-09  9 2020-10  5 2020-12  3 2021-01  1 2021-02  5 2021-03  7 2021-04  4 2021-05  4 2021-06  1 2021-07  7 2021-08  2 2021-09  8 2021-10  9 2021-11  16 2021-12  14 2022-01  7 2022-05  1 2022-08  3 2022-09  2 2022-10  2 2022-12  5 2023-01  3 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1 2024-04  1 2024-08  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript 加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。