@hunter129

天天学习,好好向上!

   :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  21 随笔 :: 5 文章 :: 37 评论 :: 0 Trackbacks

2013年9月16日 #

即日起此地不再更新,请访问 http://www.xiegq.com/
posted @ 2013-09-16 13:16 hunter129 阅读(88) | 评论 (0)编辑 收藏

2013年7月31日 #

本系列文章由作者@hunter129 翻译,转载请注明出处。

今天是第三章的剩余部分:4.性能度量指标,5.分代收集的基本原理。

性能度量
   
一些指标用来评估垃圾收集的性能,包括:

    吞吐量(Throughput)
        一个很长的周期中,除去花费在垃圾收集上的时间占总时间的百分比。
    垃圾收集开销(Garbage collection overhead)
        与吞吐量相反,这是垃圾收集占总时间的百分比。
    (译注:为什么需要两个指标呢?对于并发的垃圾收集算法,垃圾收集的部分任务和应用系统同时运行导致上述两个指标加起来会大于100%)
    暂停时间(Pause time)
        垃圾收集发生时,应用系统暂停的时间。
    收集频率(Frequency of collection)
        垃圾收集相对于应用系统运行发生的频率。
    占用空间(Footprint)
        一种大小的指标,例如堆大小。
    反应时间(Promptness)
        对象变成垃圾之后到内存可用的时间
        
一个交互式应用需要较低的暂停时间,反之持续的执行时间对于非交互式应用更加重要。一个实时应用程序要求在垃圾收集中的暂停以及收集
器的整个周期拥有较少的抖动。运行在个人计算机或嵌入式设备中的应用可能主要关心小的空间占用。

分代收集

使用分代(generational collection)收集技术时,内存分为很多代(generations),分离的存储池存储不同年龄的对象。例如,最通用的配置
中有两代:一个用于存放年轻的对象,另一存放年老的对象。

不同的代使用不同的算法执行垃圾收集任务,每个算法会基于本代独特的特征进行优化。分代的垃圾收集基于一种被称为弱分代假设(weak
generational hypothesis),它是关于在几种语言(包括java语言)编写的应用程序中观察到的结果:

    大部分的分配的对象不会被引用(存活)很长时间,这些对象在年轻的时候就死掉了
    年老对象引用年轻对象的情况很少出现
   
年轻代的收集发生的相对频繁、有效、快速,因为年轻代的空间通常比较小并且有很多的对象都不再被引用。

在年轻代几次收集后仍然生存的对象最终会晋升(promoted)或者被授予(tenured)到年老代。如图1。年老代一般比年轻代大,并且增长的速度
很慢。结果是,年老代的收集很少发生,但是会花费更长的时间才能完成。

 
        图1 分代的垃圾收集
   
为年轻代设计的收集算法主要关注在速度方面,因为垃圾收集经常发生。另一方面,在空间方面更有效率的算法管理着年老代,因为年老代占据了
大部分的堆空间并且年老代的垃圾密度比较低。

此文已转移到:http://www.xiegq.com/2013/09/16/39.html
posted @ 2013-07-31 17:03 hunter129 阅读(142) | 评论 (0)编辑 收藏

2013年7月29日 #

本系列文章由作者@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 @ 2013-07-29 21:50 hunter129 阅读(215) | 评论 (0)编辑 收藏

2013年7月22日 #

本系列文章由作者@hunter129 翻译,转载请注明出处。

第二章 直接 VS 自动内存管理

内存管理是这样的一些过程,识别哪些对象不再有用,回收(释放)这些对象使用的内存,使这些内存在随后的分配中可用。在一些编程语言中,
内存分配是程序员的责任。这项复杂的任务导致了很多常见的错误,如怪异、错误的程序行为和程序崩溃。结果是,开发人员很大比例的时间都
在调试解决这些错误。

在直接内存管理的程序中经常犯的一个错误是悬挂引用(dangling references)。对象使用的空间被回收时,可能还有其他对象引用着。如果
一个对象拥有这样(悬挂)的引用,当它试图访问原始对象时,很可能这块空间已经分配给了新的对象,结果导致了未预期的访问。

另外一个在直接内存管理中常见的错误是内存泄露(space leaks)。内存分配完不再使用后却没有释放就会产生这样的错误。例如,你打算释放
一个链表(linked list)使用的空间时犯了一个错误,只回收了链表的第一个对象,其余的对象就不再被引用了,然而这些对象脱离了程序的控
制,再也无法使用或恢复。如果产生了足够的泄露,内存将持续消耗,直到再也没有可用的部分。

作为替代方案,一种称为垃圾收集(garbage collector)的自动内存管理方法正在被广泛使用,尤其是在现代的面向对象语言中。自动内存管理
使得编写出更多抽象的接口、更多稳定代码成为可能。

垃圾收集避免了悬挂引用问题,因为被某处引用的对象永远不会被收集,内存不会被释放。垃圾收集同样解决了上面提到的内存泄露问题,因为不
再被引用的内存将自动释放。
(译注:实际上java中依然有“内存泄露”问题,只是这种泄露与上文中提到的传统上的泄露不同。可以理解为对内存的不恰当使用,会导致垃圾收
集频繁发生[本应存储对象的没有存储下来],或OOM错误[本来应释放的内存没有释放]。)

上一篇:JAVA内存管理(一)综述和介绍
此文已转移到:http://www.xiegq.com/2013/09/14/25.html
posted @ 2013-07-22 21:55 hunter129 阅读(165) | 评论 (0)编辑 收藏

2013年7月21日 #

本系列文章由作者@hunter129 翻译,转载请注明出处。

准备发一系列帖子,主要介绍java内存管理机制。
主要内容是对sun的内存管理白皮书《Memory Management in the Java HotSpot™ Virtual Machine》的翻译,也会加上自己的理解。
英文不好,我慢慢翻译,大家慢慢看。当然可以去看原版,作为附件上传了。

这是第一篇帖子,主要内容是白皮书的第一章,对整篇文档的介绍。

第一章 介绍
Java的一个长处就是提供了自动内存管理机制,因此屏蔽了开发人员进行直接内存管理的复杂性。
这篇文章提供了一个针对J2SE 5内存管理的概览。描述了垃圾收集器(garbage collectors)如何有效的进行内存管理,并给出了一些关于收
集器的选择和收集器运行时内存区域大小配置的建议。这篇文章还列出了影响垃圾收集器(garbage collector)行为最常用的选项,并且提供
了很多详细文档的链接,因此本文可以作为参考资料使用。

第二章为初学者介绍自动内存管理的概念。本章会简单的讨论一下自动内存管理和程序员直接内存管理。

第三章整体介绍了垃圾收集的概念、设计决策和性能度量。同时,介绍了基于对象生命周期的分代内存管理机制,这是一种常用的内存组织方式。
这种方法已经被证明在减少垃圾收集暂停时间、很宽泛应用范围内的整体消耗方面很有效。

剩下的部分是针对HotSpot JVM(译注,HotSpot JVM是Sum/Oracle 开发的一种JVM,其他的还有BEA/Oracle的JRockit,IBM的J9 VM等)的内容。
第四章介绍了4钟垃圾收集器,其中一个是在J2SE 5.0 update6中增加的,并且描述了分代的内存组织。对于每种垃圾收集器,简要描述他们使用
的算法类型和调优参数

第五章描述了一种在J2SE 5.0提供的新技术,它会根据应用系统运行的平台和操作系统自动选择垃圾收集器和堆大小,并根据用户行为动态进行
垃圾收集优化。这种技术称为功效学(ergonomics)。

第六章给出了一些垃圾收集器的选择和配置的推荐配置,同时也提供了一些处理OutOfMemoryError错误的建议。第七章简要描述了一些用于垃圾收
集性能(garbage collection performance)评估的工具。第八章列出了用于控制垃圾收集器的选择和行为最常用的命令行参数。最后,第九章提
供了更多涉及这篇文章内容的详细文档。

附件请移步金山快盘下载:http://www.kuaipan.cn/file/id_60654657730512059.htm

此文已转移到:http://www.xiegq.com/2013/09/11/12.html
posted @ 2013-07-21 23:03 hunter129 阅读(282) | 评论 (1)编辑 收藏

仅列出标题  下一页