主要根据以下3篇博客做的整理

http://blog.csdn.net/zsuguangh/article/details/6429592

http://www.cnblogs.com/ywl925/p/3925637.html

http://blog.csdn.net/zouxinfox/article/details/1594216

总的来说分为两大类,引用计数法和跟踪法

1、引用计数法

使用引用计数器来区分活对象和不再使用的对象。

堆中的每个对象对应一个引用计数器。每当创建一个对象并赋给一个变量时,引用计数器置为1。当对象被赋给任意变量时,引用计数器加1;当对象出了作用域后(该对象丢弃不再使用),引用计数器减1;一旦引用计数器为0,对象就满足了垃圾收集的条件。

优点:垃圾收集快,试用于实时环境。

缺点:无法检测出循环引用。

2、跟踪法

tracing算法是为了解决引用计数法无法检测出循环引用的问题而提出,它使用了根集的概念。

这种方法把每个对象看作图中一个节点,对象之间的引用关系为图中各节点的邻接关系。从根集开始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象。

优点:能检测出循环引用,较为常用。

下面是一些常用的垃圾回收算法

1、标记-清除收集器

这种收集器首先遍历对象图并标记可到达的对象,然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。并且,由于它只是清除了那些未标记的对象,而并没有对标记对象进行压缩,导致会产生大量内存碎片,从而浪费内存。

2、标记-压缩收集器

有时也叫标记-清除-压缩收集器,与标记-清除收集器有相同的标记阶段。在第二阶段,则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。

3、复制收集器

该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。它开始时把堆分成一个对象区和多个空闲区,程序从对象区为对象分配空间,当对象满了,基于coping算法的垃圾回收就从根集中扫描活动对象,并将每个活动对象复制到空闲区(使得活动对象所占的内存之间没有空闲间隔),这样空闲区变成了对象区,原来的对象区变成了空闲区,程序会在新的对象区中分配内存。

一种典型的基于coping算法的垃圾回收是stop-and-copy算法,它将堆分成对象区和空闲区域区,在对象区与空闲区域的切换过程中,程序暂停执行。

4、增量收集器

增量收集器把堆栈分为多个域,每次仅从一个域收集垃圾。这会造成较小的应用程序中断。

5、分代收集器

stop-and-copy垃圾收集器的一个缺陷是收集器必须复制所有的活动对象,这增加了程序等待时间,这是coping算法低效的原因。在程序设计中有这样的规律:多数对象存在的时间比较短,少数的存在时间比较长。因此,generation算法将堆分成两个或多个,每个子堆作为对象的一代 (generation)。由于多数对象存在的时间比较短,随着程序丢弃不使用的对象,垃圾收集器将从最年轻的子堆中收集这些对象。在分代式的垃圾收集器运行后,上次运行存活下来的对象移到下一最高代的子堆中,由于老一代的子堆不会经常被回收,因而节省了时间。

6、自适应收集器

在特定的情况下,一些垃圾收集算法会优于其它算法。基于Adaptive算法的垃圾收集器就是监控当前堆的使用情况,并将选择适当算法的垃圾收集器。

7、并发收集器

并发收集器与应用程序同时运行。这些收集器在某点上(比如压缩时)一般都不得不停止其他操作以完成特定的任务,但是因为其他应用程序可进行其他的后台操作,所以中断其他处理的实际时间大大降低。

8、并行收集器

并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多CPU机器上使用多线程技术可以显著的提高java应用程序的可扩展性。

例子:火车算法

垃圾收集算法一个很大的缺点就是难以控制垃圾回收所占用的时间,以及何时需要进行垃圾回收。火车算法是分代收集器所用的算法,目的是在成熟对象空间中提供限定时间的渐进收集。目前应用于Hotspot虚拟机上。

在火车算法中,内存被分为块,多个块组成一个集合。为了形象化,一节车厢代表一个块,一列火车代表一个集合,见图一

注意每个车厢大小相等,但每个火车包含的车厢数不一定相等。垃圾收集以车厢为单位,收集顺序依次为。这个顺序也是块被创建的先后顺序。

垃圾收集器先从块开始扫描直到,如果火车四个块中的所有对象没有被火车的对象引用,而只有火车内部的对象相互引用,则整个火车都是垃圾,可以被回收。

如图二,车厢,可见,火车没有引用火车的对象,则整个火车都是垃圾。

中有对象被其它火车引用,见图三,扫描车厢时发现对象引用,则将对象转移到车厢,然后扫描引用的对象也转移到车厢,然后扫描是否引用其它对象,如果引用了其它对象则也要转移,依次类推。扫描完火车的所有对象后,剩下的没有转移的对象都是垃圾,可以把整个火车都作为垃圾回收。注意如果在转移时,如果车厢空间满了,则要在火车末尾开辟新的车厢,将新转移的对象都放到,即火车的尾部)

补充说明:垃圾回收器一次只扫描一个车厢。图三中的对象B与C并不是立即被回收,而是先会被转移到火车1的尾部车厢。即扫描完1.1后,B被转移到火车1尾部,扫描完1.3后,C被转移到车尾。等垃圾收集器扫描到火车1尾部时,如果仍然没有外部对象引用它们,则B和C会被收集。

火车算法最大的好处是它可以保证大的循环结构可以被完全收集,因为成为垃圾的循环结构中的对象,无论多大,都会被移入同一列火车,最终一起被收集。还有一个好处是这种算法在大多数情况下可以保证一次垃圾收集所耗时间在一定限度之内,因为一次垃圾回收只收集一个车厢,而车厢的大小是有限度的。

程序中减少gc开销的措施

根据上述GC的机制,程序的运行会直接影响系统环境的变化,从而影响GC的触发。若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响。为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销。具体措施包括以下几个方面:

(1)不要显式调用System.gc()

此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。

(2)尽量减少临时对象的使用

临时对象在跳出函数调用后,会成为垃圾,少用临时变量就相当于减少了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,减少了主GC的机会。

(3)对象不用时最好显式置为Null

一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。

(4)尽量使用StringBuffer,而不用String来累加字符串

由于String是固定长的字符串对象,累加String对象时,并非在一个String对象中扩增,而是重新创建新的String对象,如Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。避免这种情况可以改用StringBuffer来累加字符串,因StringBuffer是可变长的,它在原有基础上进行扩增,不会产生中间对象。

(5)能用基本类型如Int,Long,就不用Integer,Long对象

基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。

(6)尽量少用静态对象变量

静态变量属于全局变量,不会被GC回收,它们会一直占用内存。

(7)分散对象创建或删除的时间

集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片,从而增加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC的机会。

6种java垃圾回收算法_Java垃圾回收算法相关推荐

  1. 6种java垃圾回收算法_Java垃圾回收机制

    Java垃圾回收机制 说到垃圾回收(Garbage Collection,GC),很多人就会自然而然地把它和Java联系起来.在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,这一切都交给 ...

  2. 垃圾回收算法_Java 垃圾回收算法与几种垃圾回收器

    一.如何确定某个对象是"垃圾"? 目前主流垃圾回收器都采用的是可达性分析算法来判断对象是否已经存活,不使用引用计数算法判断对象时候存活的原因在于该算法很难解决相互引用的问题.如何确 ...

  3. java垃圾回收菜鸟_java垃圾回收机制

    1:对象可能不被垃圾回收 2:垃圾回收并不等于"析构" 3:垃圾回收只与内存有关,为了回收程序不再使用的内存 java虚拟机采用了"自适应"的垃圾回收机制,即& ...

  4. java 垃圾回收 新生代_Java垃圾回收

    一.概述 Java垃圾回收器实现内存的自动分配和回收,这两个操作都发生在Java堆上(还包括方法区,即永久代).垃圾回收操作不是实时的发生(对象死亡不会立即释放),当内存消耗完或者是达到某一指标(th ...

  5. java gc回收算法_Java GC回收算法-判定一个对象是否可以回收

    开源推荐 推荐一款一站式性能监控工具(开源项目) Pepper-Metrics是跟一位同事一起开发的开源组件,主要功能是通过比较轻量的方式与常用开源组件(jedis/mybatis/motan/dub ...

  6. java 回收策略_Java堆回收策略

    一.起源 1960年Lisp语言: 第一门真正使用内存动态分配和垃圾回收的语言. 二.概要 线程相关:程序计数器.虚拟机栈.本地方法栈,不需要考虑垃圾回收 Java堆.方法区:需要考虑垃圾回收 三.垃 ...

  7. java算多元回归方程_java多元线性回归算法

    多元线性回归的计算方法摘要 在实际经济问题中,一个变量往往受到多个变量的影响.例... STLyy UQ 在多元线性回归分析中,回归平方和表示的是所有 k 个自变量对 y 的变差的总影响,它可以 按公 ...

  8. java简述垃圾回收原理及算法_Java垃圾回收原理和算法

    ·内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可.垃圾回收器将负责回收所有 ...

  9. java 二维链表_Java数据结构与算法----数组与链表

    数据类型 1 数据类型介绍 数据类型的分类(按照结构划分):线性结构和非线性结构 线性结构:线性结构作为最常用的数据结构,其特点是数据元素之间存在一对一的线性关系 线性结构有两种不同的存储结构,即顺序 ...

最新文章

  1. FTP搭建网络yum源
  2. Dao层系列-4-Hibernate Spring Annotation
  3. cmake教程(为什么要用cmake?)(cmake编译opencv)(就是个跨平台的编译工具Linux、windows)(很重要,必须得学)(报错解决方案)opencv编译
  4. html点击圆点箭头分页,css实现小箭头的实现方式
  5. iOS手势操作简介(六)
  6. printf 宏 调试技巧
  7. 从环境搭建到回归神经网络案例,带你掌握Keras
  8. python复数类型转换_Python 复数数据类型详解(complex)[学习 Python 必备基础知识][看此一篇就够了]...
  9. 关于web.xml中不能识别taglib的问题
  10. IP地址的定义和含义
  11. anaconda下载 (清华镜像)
  12. Cadence OrCad Allegro SPB 16.6 下载及安装破解指南
  13. 计算机软件毕业论文周记,软件毕业设计周记.docx
  14. (转)技嘉 MA790FXT-UD5P搭配AMD X4 965超频解析
  15. 关于微信无法登陆网页版的问题
  16. 可视化展示炫酷3D图表
  17. Graham扫描法求解二维凸包问题
  18. 【面试相关】202006面试总结
  19. 让我们和机器一起聊天
  20. 【PAT甲级】1146 Topological Order

热门文章

  1. 上海交大计算机考研报录比,上海交通大学2016年至2019年考研报录比统计数据分析...
  2. Swift Programming Tutorial for Beginners-14day Tutorial
  3. 中秋节和教师节喜相逢,VR云游让思乡宅家有归属
  4. @淘宝 @支付宝 帐号被盗,现已吓尿
  5. 深入解读C语言随机数函数和如何实现随机数
  6. Codeforces Round #770 (Div. 2) ABCD题解
  7. yjv是电缆还是电线_yjv电缆是硬线还是软线
  8. 建站百科|你的网站运营失败可能是因为ta—网站风格及框架规划
  9. windows/prefetch文件夹能删吗?里面都是些什么文件,有什么作用??
  10. linux内核提取ret2usr,Linux内核实验作业七