1.垃圾收集算法
现在的垃圾回收分带理论其实已经始于几十年前了,java的回收算法和垃圾回收器一直都在改进从未出现一款能适合所有场景的回收机制。所以我们进行垃圾回收的核心思想是 结合具体业务框架技术等客观条件合理选择垃圾回收器并分配资源。
现在这个机制:
一般将java 堆分为新生代和老年代 在新生代中的一般是我们java中朝生夕死的对象每次垃圾回收都会有大约99%的对象死去。现在一般采用复制算法。
老年代的对象存活比例较高。这里推荐大家先了解什么对象存入新生代,什么对象存入老年代。什么对象存入栈中。如何你把上面的整个理解了80%以上 那么就可以继续读下去了。对于老年代我们应该采用标记清除或者标记整理。应该根据自己数据特点选择是否需要整理。以及老年代做几次GC整理一次。
1.标记清除算法
主要分为两个阶段标记 和清除阶段 可以正着标记也可以反着标记 在标记完成后统一回收。但是存在两个问题:
1.效率问题。
2.空间内会产生大量内存碎片。(数组和某些大对象需要连续的空间存放。)
2.标记整理:
就是清除后统一进行整理,虽然这里的地址会被改变,但是利用计算机底层的一些屏障机制等
可以改变我们的引用地址。
针对老年代对象的存亡特征,1974年Edward Lueders提出了另外一种有针对性的“标记-整 理”(Mark-Compact)算法,其中的标记过程仍然与“标记-清除”算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向内存空间一端移动,然后直接清理掉边界以外的内存, 标记-复制算法在对象存活率较高时就要进行较多的复制操作,效率将会降低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法。 标记-清除算法与标记-整理算法的本质差异在于前者是一种非移动式的回收算法,而后者是移动式的。是否移动回收后的存活对象是一项优缺点并存的风险决策: 如果移动存活对象,尤其是在老年代这种每次回收都有大量对象存活区域 |