JVM GC Heap

JVM的一个关键特征是它的GC Heap。Heap保存了Java运行期的所有对象,数组。GC可以动态释放Heap中不再使用的空间。在Java程序里,一个对象可以通过关键字new来创建,“创建”对于JVM来说就是在Heap里分配一块空间保存新对象。GC,也就是Garbage collection,既清除Heap里不再使用的对象。为了清除这些对象,GC必须调用这些对象的Finalizer。另为GC还可以合并Heap中的空间碎片。Heap空间碎片是由于不断分配和释放造成的。如果不合并这些碎片,即使有足够的空间,由于没有足够大的连续空间而不得不扩大Heap空间,扩大空间会降低运行性能。

GC算法

目前已经实现了很多GC算法,处理Sun之外,IBM,Symantec,Microsoft,HP,以及各种开源组织都投入到这项研究。那他们竞争的关键就在于GC的Heap。任何一个GC算法都必须做两件事,一,它必须能找到所有的垃圾对象,也就是不再使用的对象,二,它必须可以回收垃圾对象空间。

通常,搜索垃圾的工作,首先建立一组类似于树的结构,树根为root,节点则叫做对象引用。任何一个对象如果在各种结构里能找到它的引用,则成为该对象可使用(reachable)或称对象状态是活动的(live),而任何没有在结构里找到引用的对象则称为垃圾。在JVM里,所有的对象都保存在Heap里,本地变量则保存在Java Stack里,每个线程都有自己的Stack。每个本地变量或是对象引用,或是基本数据类型,例如int, char或float。因此,线程里保存的只是对象的引用,而对象的实例都保存在Heap中。当一个线程结束,线程里对象引用将被删除,那么这些对象就有可能成为Heap中的垃圾。(“有可能”是因为对象有可能在其他线程中被引用。)

区别可使用对象和垃圾对象有两种方法,他们是引用计数和遍历搜索。引用计数就是在Heap中记录各个对象的引用数。遍历搜索是在树结构里搜索对象引用,并在Heap里标记被引用的对象,遍历后,那些没有标记的对象则是垃圾。

引用计数器

引用计数器保存在对象里,当一个对象被创建时,计数器为1。当其他对象引用这个对象时,该对象的引用计数器加1。当对这个对象的引用结束时,计数器减1。引用计数器为0时,则被看作是垃圾。该算法的缺点是没有遍历功能。该算法已经过时,现在的JVM都采用第二种方法遍历搜索法。

遍历搜索器

        搜索器从树结构的根节点开始遍历,寻找对象引用,并把被引用的对象做标记(Mark)。遍历之后,未作标记的对象被视为垃圾,可被GC回收(Sweep)。

碎片整理器

        Heap碎片整理(Compacting collector)有两个步骤,整理和拷贝。这两步用来移动Heap中的对象从而减少碎片。既然好移动对象的位置,当要也要更新对象的引用,但是更新对象引用是会降低VM的性能,因此建立一个对象句柄表,对象引用指向对象句柄,当对象移动时,更新对象的句柄,而不用改变对象引用的值。拷贝步骤就是将Heap的对象移动到新的位置。为了提高拷贝的性能,VM被分为两个区,VM在内只能使用两个中的一个。当使用中的区没有空间后,将所有的对象从该空间拷贝到另一个空间,并继续在另一个空间工作,直到另一个空间满了为止,再把所有对象拷贝回原来的空间。该方法的代价就是需要花费2倍的空间。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/tyrone1979/archive/2006/07/23/965566.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值