码迷,mamicode.com
首页 > 编程语言 > 详细

Java GC 垃圾回收算法 内存分配

时间:2015-06-21 20:56:12      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

垃圾回收(Garbage Collection, GC)是Java不同于c与c++的重要特性之一。

他帮助Java自动清空堆中不再使用的对象。

由于不需要手动释放内存,程序员在编程中也可以减少犯错的机会。

利用垃圾回收,程序员可以避免一些指针和内存泄露相关的bug(这一类bug通常很隐蔽)。

垃圾回收实际上是将原本属于程序员的责任转移给计算机。

 

GC需要完成的3件事情:

  哪些内存需要回收

  什么时候回收

  如何回收

 

1 回收那些对象?

 

   在Java中采用可达性分析算法来判定对象是否存活,是否可以被回收。

   这个算法通过一系列的被称为”GC Root”的对象作为根节点,

   从他们开始向下搜索,搜索走过的路径被称为引用链(Reference Chain).

   当一个对象没有一条引用链与GC Root 连接时,

   即从GC Root 到这个对象是不可达的,说明这个对象是不可用的。

   如图示:

 技术分享

object5 object6 object7 虽然互联互通 

但是他们到GC Root是不可达的 

所以他们将被判定为可以回收的对象

 

那么有一个重要的问题是 what is GC Root?

在Java语言中,可以看做是GC Root的是:

  虚拟机栈中引用的变量 (可理解为方法中的局部变量)

  方法区中的类静态属性引用的对象

  方法区中的常量引用的对象

  本地方法栈中的JNI(native方法)引用的对象

 

2 垃圾回收算法

 

 2.1 标记-清除算法

      

  顾名思义,该方法分为标记和清除2个过程

  标记:将所有需要回收的对象区域进行标记

  清除:清除所有配标记的区域里的对象

技术分享

算法不足之处:

 

效率问题:标记和清除的效率都不高

空间问题:清除后产生的空间是不连续的碎片

          无法满足后续运行中大对象的需求

 

2.2 复制算法

 

将整个空间划分2个相等的区域,每次只使用其中一个区域

当一块内存不够时,就将活着的对象复制到另一块内存

然后将第一块的内存全部回收。

这样每次对整个半区回收,就不会有内存碎片的情况,实现简单,运行高效

技术分享

 

问题:  该算法的代价就是可以内存大小缩小为原来的一半

 

解决:现在商用的虚拟机都采取复制算法.

      但由于所有的对象是朝生夕死的,所以并不是按照1:1的比例来划分内存的

      而是将内存划分为一块较大的Eden区(new一个对象是就是在这里面分配空间)

      和2块Survivor区域。每次使用Eden和一块Survivor。

      当回收的时候,将Eden和Survivor区中还存活的对象一次性赋值到另一块Survivor中

      最后清理掉原来使用过的Eden和Survivor区

      这3个区域也被称为新生代。HotSpot的默认新生代各区域比例如下:

   技术分享

 

     每次新生代中可用的空间为整个新生代的90%, 即80% Eden + 10% 1个Survivor

     此时只有10% 1个Survivor 会被’浪费’

 

     如果另一块Survivor区域存放不下Eden和Survivor区存活下来的对象

     就要依靠其他区域来存放 即老年代

 

2.3 标记-整理算法

 

类似于标记-清除算法,先标记所有可以回收的区域,然后不是直接回收,

而是把所有存活的对象都移动到一端,然后直接清理掉端边界以外的区域

技术分享

标记-整理算法和标记-清除算法常用于老年代的回收

老年代存放的对象存活的时间较长

而且垃圾回收的频率不如新生代的频繁

 

Java GC 垃圾回收算法 内存分配

标签:

原文地址:http://www.cnblogs.com/wihainan/p/4592323.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!