JAVA中垃圾回收器的工作原理

1清理

        Java中有垃圾回收器负责回收无用对象占据的内存资源,但是也有特殊情况,垃圾回收器只知道释放那些经由new分配的内存,对于非使用new分配的内存,垃圾回收器就不知道该如何释放,为了应对这种情况,Java允许在类中定义一个名为finalize()的方法。工作原理假定是这样的:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法,并且在下一次垃圾回收动作发生时,才会真正的回收对象占用的内存。

1.1 垃圾清理:

        1)对象有可能不被垃圾回收;

        2)垃圾回收不等于析构;

        3)垃圾回收只与内存有关,也就是说对于与垃圾回收有关的任何行为来说(尤其是finalize()方法),它们必须同内存及其回收有关。

1.2 垃圾回收器是如何工作的

     java中垃圾回收器对于提高对象的创建速度有着明显的效果,在某些java虚拟机中,堆的实现更像一个传送带,每分配一个新对象,它就往前移动一格,这样堆指针只是简单的移动到尚未分配的区域。但是堆未必完全像传送带那样工作,如果真这样做的话,势必会导致频繁的内存页面调度,这会显著的影响性能,最终在创建了足够多的对象后,内存资源将会耗尽。不会出现这样问题的秘密在于垃圾回收器的介入。当垃圾回收器工作时,将一面回收空间,一面使堆中的对象紧凑排列,这样堆指针就可以很容易的移动到更靠近传送带的开始处。通过垃圾回收器对对象重新排列,实现了一种高速的、有无限空间可共分配的堆模型。

      想要理解java中的垃圾回收,先了解其他系统中的垃圾回收机制会更好点,下面介绍几种几种垃圾回收技术:

       1)引用计数:是一种简单但速度很慢的垃圾回收技术,每个对象都含有一个引用计数器,当有引用连接之对象时,引用计数加1,当引用离开作用域或者被置为null时,引用计数减1。虽然管理引用计数的开销不大,但这项开销在整个程序生命周期中将持续发生,垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0时,就释放其占用的空间。但是这个方法有个有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为0”的情况。引用计数常用来说明垃圾收集的工作方式,并未应用于任何一种java虚拟机中。

        2)自适应的垃圾回收技术:自在一些更快的模式中,依据的思想是:对于任何活的对象,一定能最终追溯到其存活的堆栈或静态存储区之中的引用,遍历所有的引用,就能找到活的对象,这样就解决了“交互引用的对象组”问题。

        有一种做法名叫停止-复制,这种做法需要先暂停程序的运行,所以这种不属于后台回收模式,然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾,当对象被复制到新堆时,它们是一个挨着一个的,所以新堆保持紧凑排列,然后就可以简单直接的分配新空间了。但是这种方式效率会降低,这里有两个原因,首先,得有两个堆,然后得在这两个分离的堆之间来回倒腾,从而维护需要比实际对一倍的空间。某些java虚拟机的处理方式是按需从堆中分配几块较大的内存,复制动作发生在这些大块内存之间;第二个问题在于复制,程序进入稳定状态之后,可能只会产生少量垃圾,甚至没有垃圾。但是复制式回收器仍然会将所有内容复制到另一处,这很浪费。

        为了避免上面的情形,一些java虚拟机会进行检查,要是没有新垃圾产生,就会转换到另一种工作模式,即“自适应”,这种模式被称为标记-清扫,这种方式速度很慢,但是程序只会产生少量垃圾甚至不会产生垃圾时,它的速度就很快了。标记-清扫所依据的思路同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象,每当找到一个存活对象,就会给对象设一个标记,这个过程不会回收任何对象,只有全部标记工作完成的时候,清理动作才会开始。在清理过程中,没有标记的对象将被释放,不会发生任何复制动作,所以剩下的堆空间是不连续的,垃圾回收器要是希望得到连续空间的话,就需要重新整理剩下的对象。标记-清扫也需要在程序暂停的情况下才能进行。

        综上所述,内存分配以较大的“块”为单位,如果对象较大,它会占用单独的块。严格来说,停止-复制要求在释放旧有对象之前,必须把所有存活对象从旧堆复制到新堆,这将导致大量内存复制行为。有了块之后,垃圾回收器在回收的时候就可以往废弃的块里拷贝对象了。每个块都用相应的代数来记录它是否还存活。通常,如果块在某处被引用,其代数会增加,垃圾回收器将对上次回收动作之后新分配的块进行整理,垃圾回收器会定期进行完整的清理动作,大型对象仍然不会被复制(只是其代数会增加),内涵的小型对象那些块则被复制并整理。

        java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低的话,就切换到标记-清扫方式,同样,java虚拟机会跟踪标记-清扫的效果,要是堆空间出现很多碎片,就切换回停止-复制方式,这就是自适应技术。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值