@hunter129

天天学习,好好向上!

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  21 随笔 :: 5 文章 :: 37 评论 :: 0 Trackbacks
本系列文章由作者@hunter129 翻译,转载请注明出处。

第三章包括5个小部分,1.垃圾收集的基本概念,2.优秀垃圾收集器的特征,3.收集器的设计选择,4.性能度量指标,5.分代收集的基本原理。
内容比较长,我会分成2篇帖子发,本章的内容是通用的,也就说这些内容同样适用于其他JVM的实现,甚至其他语言的VM的垃圾收集实现。
今天的部分包括1-3,以下是正文:

第三章 垃圾收集概念

垃圾收集器负责以下几个事情:
    1.分配内存
    2.确保被引用的对象留在内存中
    3.回收执行中代码的引用无法到达的对象占用的内存(译注:强调执行中是为了排除对象互相引用的情况。A、B互相引用,但没有任何执行中
    代码引用他们,A、B也应被回收)
   
对象被引用称为活着的(live)。不再被引用的对象称为死掉的(dead),术语叫垃圾(garbage)。发现和释放(或者叫回收(reclaiming))
这些垃圾占用的空间叫做垃圾收集(garbage collection)。

垃圾收集可以解决很多内存分配问题,却不能解决所有的内存分配问题。例如,你可以创建对象并无限期的引用着直到没有内存可用。垃圾收集在
使用其自身的时间和资源上是一个复杂的任务。

垃圾收集器负责的内存是由精确的算法来组织、分配和回收的,并对开发人员隐藏。空间通常从一个被称为堆(heap)的非常大的内存池分配出来。
垃圾收集的时间由垃圾收集器决定。通常,整个堆或堆的一部分被填满或者达到某个阈值的时候,会触发垃圾收集。

满足内存分配的请求是一个困难的任务,这其中包括要从堆中找到一个足够大的内存块。对于大部分的动态内存分配算法,其主要的问题是需要在
保持内存分配和回收效率的同时避免内存碎片。

优秀的垃圾收集器的特征

垃圾收集器必须是安全有效的。就是说,使用中的数据永远不能被错误的释放,同时在很少的几个收集周期内垃圾就应该被回收。

垃圾收集器的执行效率也必须很优秀,暂停时间不能太长。暂停的时候,应用系统是不运行的。然而,像大部分的计算机系统那样,这里也必须在
时间、空间、频率之间做出权衡。例如,堆很小的时候,垃圾收集的速度很快但堆被填满的速度更快,这样就需要更频繁的垃圾收集。相反的,大
的堆填满的速度慢,收集的频率也慢,但花费的时间会比较长。

另一个特征是有限的内存碎片(fragmentation)。当垃圾对象的内存释放后,释放的空间会在各种各样的区域形成小块的空隙以至于可能导致没
有一个足够大的连续区域分配给较大的对象。一种减少内存碎片的方法叫做压缩(compaction),在下面垃圾收集器的设计决策部分会讨论到。

可扩展性同样很重要。在多核系统上运行的多线程程序中,内存分配、垃圾收集都不能成为瓶颈。

设计决策

设计和选择垃圾收集算法时必须做出一系列选择:
   
    串行还是并行
        在串行收集中,同一时间只做一件事情。例如,即便有多个cpu可用,却只有一个进行收集工作。当使用并行收集时,垃圾收集任务会分
    成几个小的部分,这些小的部分在不同的cpu上同时执行。同时执行的操作使得收集速度更快,它的代价是额外的复杂性和可能更多的内存碎
    片。

    并发的(Concurrent)还是停止一切(Stop-the-world)
        当执行停止一切(Stop-the-world)的垃圾收集时,应用系统在收集期间完全暂停(suspended)了。另外一种选择是,一个或多个垃圾
    收集任务可以和应用系统同时并发的执行。通常,一个并发的收集器,大部分工作并发的执行,但仍会有一些短暂的暂停(stop-the-world
    pauses)。停止一切的垃圾收集比并发收集更简单,因为整个堆都冻结了,在收集期间对象不会改变。它缺点是一些应用程序不喜欢的暂停
    (paused)。相应的,并发收集的暂停时间更短,但收集器必须格外的小心,执行收集的同时应用系统可能会改变对象的状态,这会增加一
    些开销。并发收集会影响性能并且需要较大的堆内存。
   
    压缩 or 不压缩 or 拷贝
        当收集器判定内存中的对象哪些是存活的哪些是垃圾之后,收集器可以压缩(compact)内存,将所有存活的对象放到一起,从而完全的
    恢复剩余的内存。压缩之后,在第一个空闲位置分配内存将会非常的容易和迅速。可以用一个简单的指针维持下一个可分配对象的位置。相
    对压缩的收集器,非压缩(non-compacting)的收集器在原地(in-place)释放垃圾对象占用的空间,它不会像压缩的收集器那样移动存活
    的对象创建一个大的回收区。非压缩的好处是收集完成的很快,缺点是可能有内存碎片。一般来说,从原地释放的内存分配空间比从压缩的
    堆分配内存更困难些。它必须搜素堆空间找到一个足够大能容纳新对象的连续内存区域。第三种可供选择的是复制(copying)收集器,拷贝
    (或疏导evacuates)所有活动的对象到另一个不同的内存区域。它的好处是原来的区域可以直接置空,简单快速的为随后的内存分配做好准
    备,缺点是需要额外的空间和时间。

此文已转移到:http://www.xiegq.com/2013/09/15/37.html
posted on 2013-07-29 21:50 hunter129 阅读(296) 评论(0)  编辑  收藏 所属分类: java内存管理垃圾收集

只有注册用户登录后才能发表评论。


网站导航: