JVM GC-----一、垃圾回收算法

说到Java,必定绕不开GC,尽管不是Java独创的,但Java必定是使用GC的表明。GC就是垃圾回收,更直接点说就是内存回收。是对内存进行整理,从而使内存的使用尽量大的被复用。 一直想好好写一篇关于GC的文章,但是却发现要写的东西太大了,不是一篇博客能简单的介绍完的。因此打算拆分红若干篇博客,一点点的总结下来。 本篇主要介绍的是GC中的经常使用算法。这些算法被普遍的应用于各个内存管理语言的虚拟机中,或者是各大经常使用的操做系统中。 说到GC,也就是垃圾回收,那么须要作的事有两件:html

第一件是查找到哪些内存中的对象是已经废弃掉的。
第二件事是如何清理掉这些已经废弃掉的数据。
本文先来讲说后者,如何清除掉这些内存中的废弃数据。
算法

一、标记清除算法Mark-Sweep sql

 这种算法是最简单最直接的算法,也是其它算法的一些最初思路。标记清除算法其实就是对内存中的对象依次的进行判断,若是对象须要回收那么就打一个标记,若是对象仍然须要使用,那么就保留下来。这样通过一次迭代以后,全部的对象都会被筛选判(防盗链接:本文首发自http://www.cnblogs.com/jilodream/ )断一次。紧接着会对内存中已经标记的对
象依次进行清除。 这个算法比较简单粗暴,实现起来比较简单。
可是会留下两个比较麻烦的问题:
 (1)标记和清除须要两遍循环内存中的对象,标记自己也是一个比较麻烦的工做,所以这种算法的效率不是特别的高。
 (2)对于分配的内存来讲,每每是连续的比较好,由于这样有利于分配大数据的对象。假若当前内存中都是小段的内存碎片,会知道须要分配大段内存时,没有能够放置的位置,而触发内存回收。也就是空间不足而致使频繁GC和性能降低。
数据库

二、复制算法Copying 编程

我在使用数据库的过程当中,曾经遇到这样一个问题,表中的数据量相对来讲比较大,大概30万行,须要使用多个苛刻的条件删除其中的大部分数据(所以没法使用索引),而只保留其中的较少数据。常规的delete语法使用起来是超时的。因而我查看维护人员的sql,发现一个颇有意思的逻辑。首先查出数据库表中须要保留的数据,放到一张临时表中。而后完全删除掉原有的数据表。而后把这张临时建立表的表名,改成当初的表名。这是一种典型的空间换取时间的方法。而复制算法就是这样一个思路。 复制算法中,会将内存划分为两块相等大小的内存区域A/B,而后生成的数据会存放在A区,当A区剩余空间不足以存放下一个新建立的对象时,系统就会将A区中的有效对象所有复制到B区中,并且是连续存放的。而后直接清空A区中的全部对象。 因为编程语言中的对象,大部分在建立后很快就(防盗链接:本文首发自http://www.cnblogs.com/jilodream/ )会被回收掉,因此咱们须要复制的对象其实并很少。 Java中的实现是这样的: Java中将Eden和Survivor区同时做为复制算法的使用区域。Survivor又分为From区和To区。这块内容能够参考个人另一篇博客,博客中有详细的介绍:http://www.cnblogs.com/jilodream/p/6147791.html。每次GC的时候都会将Eden和Survivor的From区中的有效对象进行标记,一同复制到Survivor的To区。而后完全清除原来的Eden区和From区的内存对象。与此同时To区就是下一次回收的From区。编程语言

复制算法的缺点: 算法使用了空间换取时间的思路,所以须要一块空白的区域做为内存对象要粘贴的区域。这无疑会形成一种浪费。尤为是内存较小时。 算法每次清除无效对象时,都要进行一次复制粘贴的对象转移,所以对使用场景是有限制的。只有在有效对象占据总回收内存是很是小的时候,这种算法的性价比才会达到最高。不然大量的复制动做所浪费的时间可能要远远大于空间换取时间获得的收益。所以这种算法在Jvm中,也只被用来做为初级的对象回收。由于这时的有效对象比例最低,算法的性价比是最高的。性能

三、 标记整理算法 Mark-Compact大数据

复制算法须要一块额外的内存空间,用于存放幸存的内存对象。这无疑形成了内存的浪费。咱们还能够在原有的标记清除算法的基础上,提出了优化方案。也就是标记到的可用对象总体向一侧移动,而后直接清除掉可用对象边界意外的内存。(防盗链接:本文首发自http://www.cnblogs.com/jilodream/ )这样既解决了内存碎片的问题。又不须要原有的空间换时间的硬件浪费。因为老年代中的幸存对象较多,并且对象内存占用较大。这就使得一旦出现内存回收,须要被回收的对象并很少,碎片也就相对的比较少。因此不须要太多的复制和移动步骤。所以这种方法经常被应用到老年代中。 优化

标记整理算法的缺点: 标记整理算法因为须要不断的移动对象到另一侧,而这种不断的移动实际上是很是不适合杂而多的小内存对象的。每次的移动和计算都是很是复杂的过程。所以在使用场景上,就注定限制了标记整理算法的使用不太适合频繁建立和回收对象的内存中。spa

四、分代收集算法  Generational Collection

这种算法就是将内存以代的形式划分,而后针对状况分别使用性价比最高的算法进行处理。在Java中,通常将堆分为老年代和新生代。新建立的对象每每被放置在新生代中。而通过不断的回收,逐渐存活下来的对象被安置到了老年代中。越新的对象越可能被回收,越老的对象反而会存活的越久。所以针对这两种场景,新生代和老年代也会分别采用前文所述的两种算法进行清理。

ps:话说如今写篇博客愈来愈难了,今天觉得画个图就能够发布了,结果画图画了一个小时。哎

相关文章
相关标签/搜索