近期看了一些关于垃圾回收机制的文章,总结一下。

    垃圾回收器回收程序不在使用的对象占用的内存,也就是对象不可达,比方说对象被置为null。

要回到java的垃圾回收机制,从下面三个方面去回答:

1、哪些内存会被收回?

2、什么时候收回?

3、怎样收回?

首先,谈谈哪些对象会被收回。

    通过根搜索算法(GC Roots Tracing)推断对象是否还活着。该算法通过一系列的名为“GC Roots”的对象做为起始点,通过这些节点向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots没有不论什么引用链接(用图论来说就是从GC Roots到这个对象不可达),则说明该对象是不可用的,它们将会被判定为可回收的对象象。

其次,什么时候回收这些内存。

    cpu空暇或者内存空间不足时,进行垃圾回收,而程序猿本省无法控制何时进行垃圾回收。

最后。怎样进行垃圾回收。

Java语言规范没有明白地说明JVM使用哪种垃圾回收算法,大多数垃圾回收算法使用了根集(root set)这个概念;所谓根集就量正在运行的Java程序能够訪问的引用变量的集合(包含局部变量、參数、类变量),程序能够使用引用变量訪问对象的属性和调用对象的方法。垃圾收集首选须要确定从根開始哪些是可达的和哪些是不可达的,从根集可达的对象都是活动对象,它们不能作为垃圾被回收,这也包含从根集间接可达的对象。而根集通过随意路径不可达的对象符合垃圾收集的条件,应该被回收。

大致有例如以下方法:

1、 引用计数法(Reference Counting Collector)

   引用计数法是唯一没有使用根集的垃圾回收的法。该算法使用引用计数器来区分存活对象和不再使用的对象。

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

2、tracing算法(TracingCollector)

  tracing算法是为了解决引用计数法的问题而提出。它使用了根集的概念。基于tracing算法的垃圾收集器从根集開始扫描,识别出哪些对象可达,哪些对象不可达,并用某种方式标记可达对象,比如对每一个可达对象设置一个或多个位。在扫描识别过程中,基于tracing算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器.

  

3、compacting算法(CompactingCollector)

   为了解决堆碎片问题,基于tracing的垃圾回收吸收了Compacting算法的思想。在清除的过程中,算法将全部的对象移到堆的一端。堆的还有一端就变成了一个相邻的空暇内存区,收集器会对它移动的全部对象的全部引用进行更新,使得这些引用在新的位置能识别原来的对象。

4、copying算法(CopingCollector)

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

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

5、generation算法(GenerationalCollector)

   stop-and-copy垃圾收集器的一个缺陷是收集器必须复制全部的活动对象,这添加了程序等待时间。这是coping算法低效的原因。在程序设计中有这种规律:多数对象 存在的时间比較短,少数的存在时间比較长。

因此,generation算法将堆分成两个或多个。每一个子堆作为对象的一代(generation)。因为多数对象存在的时间比較短,随着程序丢弃不使用的对象,垃圾收集器将从最年轻的子堆中收集这些对象。在分代式的垃圾收集器运行后,上次运行存活下来的对象移到下一最高代的子堆中,因为老一代的子堆不会常常被回收,因而节省了时间。

垃圾回收的算法非常多。引用计数器算法、标记清除算法、复制算法、标记整理算法,随着发展,眼下採用较多的是分代收集 算法。 其分为新生代和老年代。新生代中适合于频繁创建。而且高死亡率。老年代中适合于存活率高的。内存的分配方式见下图。



新生代和老年代的比例为1:2。大量的行创建的对象在被创建在Eden space上,可是太大的对象(创建大的数组)将直接被创建在老年代中,避免大对象频繁的移动。大量新创建的对象将非常快的死亡,也就是变成不可达对象,将Eden上的内存空间不够时,将进行minor gc 将Eden space和from space上的内存回收。使用复制算法。将活的就可以达的对象拷贝到to space空间中。此时全部的对象‘年龄’+1,当达到一定的’年龄‘是会拷贝到老年代中,同一时候老年代也为新生代复制算法。有可能产生内存空间不足的问题提供了担保。这时候to sapce 下一步变成from space了。一直循环。老年代中。当内存空间不足时,运行full gc ,使用标记-整理算法。

最新文章

  1. mongoDB index introduction
  2. 关于xml的使用。
  3. Constructing Roads In JGShining's Kingdom(HDU1025)(LCS序列的变行)
  4. 转!!Java 基础面试题的剖析: short s1=1;s1 = s1 +1 报错? s1+=1 呢
  5. Careercup - Microsoft面试题 - 5673934611546112
  6. boa安装
  7. Android应用在不同版本间兼容性处理
  8. JAVA 快递查询接口API调用-快递鸟接口
  9. Mac使用rz、sz远程上传下载文件
  10. Python文件中文编码问题
  11. Emacs下编译C++/C程序<转>
  12. ztree树形插件
  13. instance “error” 了怎么办?- 每天5分钟玩转 OpenStack(159)
  14. django出现__init__() got an unexpected keyword argument 'mimetype‘ 问题解决
  15. BZOJ2157 旅行 模拟
  16. Html table 合并单元格
  17. h5页面 内嵌h5页面遇到的问题
  18. YOU AND ME 不见不散(转载)
  19. (转载)Rime输入法—鼠须管(Squirrel)词库添加及配置
  20. 在升级过内核的机器上安装docker遇到的一个错误

热门文章

  1. TOJ 2017: N-Credible Mazes
  2. 如何部署 sources and javadoc jars
  3. VM上完美运行macos
  4. [BZOJ1592] [Usaco2008 Feb]Making the Grade 路面修整(DP)
  5. [BZOJ1589] [Usaco2008 Dec]Trick or Treat on the Farm 采集糖果(tarjan缩点 + 记忆化搜索)
  6. 算法复习——LCA模板(POJ1330)
  7. hdu 3711
  8. msp430项目编程33
  9. Scrapy学习-4-Items类&Pipelines类
  10. hdu 4857 逆拓扑+大根堆(priority_queue)