`
hqs7636
  • 浏览: 221144 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

D 2.0 的gc

阅读更多
http://lucifer1982.wordpress.com.cn/2007/12/23/d%E8%AF%AD%E8%A8%80%E7%9A%84gc/

从目前掌握的资料来看,似乎只有D语言规范里稍稍提了一下D语言的内存模型,并没有深入描写.以下细节来自D 2.0语言运行时的实现代码,若以后运行时实现有所变更,请参考最新D运行时实现(所有代码均参考DMD的实现,GDC应该与其差别不大).

D主要有三种分配内存的途径.

    * 静态数据,分配在默认数据段上.
    * 堆栈数据,分配在线程堆栈上.
    * 垃圾收集数据,动态分配在GC Heap上.

前面的两种与C/C++没什么区别.我们主要讨论第三种.

先来看看C/C++的内存管理模式.

   1. 首先我们会为某个对象或类型分配内存.
   2. 初始化上一步所得的内存.
   3. 通过访问对象或类型成员来使用资源.
   4. 销毁资源状态,执行资源清理工作.
   5. 释放内存.

这种模式看起来相当的简单,但是却是导致很多问题的根源.想想有多少次我们忘记了释放无用的内存.想想有多少次调试的时候,内存问题是浪费我们时间的最大元凶.

GC正是为了解决该问题而产生的.它接管了上述步骤的第五步.对于一些本地资源(比如文件,数据库连接,套接字,同步对象,位图,图标等),通常在其对象的内存即将被回收时,必须执行一些资源清理工作.

下面来探讨一下D语言的GC内存分配和资源初始化.所有继承自Object的对象均在GC Heap上分配,此外还有动态数组.

D运行时内部有一个GC类.当应用程序的进程完成初始化后,GC也跟着初始化.GC内部会保留一块连续的地址空间,这段空间最初并不对应任何物理内存.该地址空间即为GC Heap.GC Heap上维护着一个指针,该指针表示下一个新建对象分配时在GC Heap中所处的位置.开始时,该指针被设置为保留地址空间的基地址.

当我们new一个对象时,D运行时会调用Object _d_newclass(ClassInfo ci)函数来创建一个新的对象.至于该函数实现细节,因为没有找到相关代码,所以无法具体描述.我们可以猜测其实现细节如下:

   1. 计算类型所需要的字节数.此外,应该还有相关的一些额外开销所需要的字节数.这些额外开销应该包含有一个类型对象指针和一个同步索引块(该同步索引块会在后面详细解说).
   2. D运行时检查保留地址空间是否满足分配新对象所需要的字节数.如果需要则commit物理内存.如果GC Heap中还有足够的剩余空间,那么对象将被分配在GC内部维护指针所指示的地方,并且所分配的地址空间中的字节被清零.接着,调用类型的实例构造器返回对象的内存地址(GC内部维护的指针会传递给this参数,而类型的静态构造函数会在main()函数前调用完毕).而在new返回对象的地址之前,GC 内部维护的指针会越过对象所处的内存区域,并指示出下一个新建对象在GC Heap中的地址.

这与C运行时库中的堆分配内存有着本质的区别.这样的内存分配方式使得分配对象的速度相当快,几乎可以与在线程堆栈中分配对象一样快!

接下来我们来看一下D语言中GC是如何工作的.

每个应用程序都有一组root.当GC开始执行时,它假设GC Heap中所有的对象都是垃圾.这样GC会查找所有的root(比如静态字段,方法参数,局部变量,CPU寄存器).如果发现root引用了一个对象,那么就mark它.接着GC继续查找,如果GC试图将一个先前已经标记过的对象再次mark时,它会停止该对象标记的路径方向上的遍历活动.这种行为有两个目的.首先,可以避免GC多次遍历;其次,如果对象之间出现了循环引用,可以避免陷入无限循环.

GC一旦检查完所有的root,便会回收那些未被mark的对象内存.接下来就到了压缩阶段.GC可能会压缩内存,也可能不会.这取决于找到的内存块容量.当GC找到比较大的连续内存块时,会把内存中的一些非垃圾对象搬移到这些连续内存块以压缩GC Heap.

显然,搬移内存中的对象将使所有所有包含这些对象指针的变量和CPU寄存器变得无效.因此,GC需要重新访问所有的root,并修改他们以使其指向这些对象的新内存位置.另外,如果对象包含有指向另一移动过的对象的字段,那么GC也会负责矫正这些字段.在GC Heap中的内存被压缩之后,GC内部维护的指针将被设置为指向最后一个非垃圾对象之后.

垃圾收集会给应用程序带来相当的性能开销,这也是使用GC时主要的负面影响.所以,GC会有一些特殊的设计来大幅提高GC的性能.D语言的GC是个基于代的垃圾收集器.引入代的唯一目的就是为了提高GC的性能.

前面讲到在创建新对象时,会创建一个同步索引块.它的目的是为了线程同步.当我们使用synchronized来创建线程安全的程序时,D运行时会把通过该同步索引块关联到一个同步锁.Windows下会关联到一个CRITICAL_SECTION,Linux则关联到一个 pthread_mutex_t.这个不能用于多进程同步.D语言的GC实现了多线程安全.

此外,D语言的析构函数不表示确定性析构,但是通过delete表达式却实现了确定性析构的效果.当一些昂贵的资源需要及时析构时,采取这种方式是有效的.大多数的资源交给GC来回收即可.

唯一担心的是这种方式的滥用,因为确定性析构很可能会造成应用程序性能的下降.这会加大GC的压力,使得GC频繁的进行垃圾回收.建议采用.NET的终结模式.
分享到:
评论

相关推荐

    thBase:我的D 2.0编程语言的GC免费标准库

    基础我的D 2.0编程语言的GC免费标准库目前,这仅适用于Windows上的dmd 2.063和gdc 2.060 您将需要Visual Studio 2008或2010和VisualD 0.3.34( )进行编译。 您将需要我的druntime和phobos修改版来编译和使用它。 ...

    D78846GC20--oracle 12c administration workshop sg2

    - **课程编号**:D78846GC20 - **版本**:Edition 2.0 | December 2014 | D89299 - **出版方**:Oracle University - **适用对象**:数据库管理员、IT专业人员、Oracle用户等。 #### 二、版权与使用限制 - **版权...

    NET Framework2.0分章节题库

    选项A和E不是最佳实践,因为WeakReference不直接用于资源清理,而强制垃圾回收(GC.Collect)通常应该避免,因为它可能导致不必要的性能开销。 第四章讲解了委托和事件,这是.NET中的多线程和异步编程的关键概念。...

    .net framework 2.0 程序设计

    选项E错误,因为不应直接调用`System.GC.Collect`,而是让垃圾回收器自动处理。 4. **异常处理**:当发生异常时,`Exception`类的`StackTrace`属性提供了引发异常的代码行的详细信息,这对于调试非常有用。选项C的`...

    thl_r16_tinav2.0_hm1375验证通过_增加打印设备ID_20170824_1447.7z

    #obj-m+= gc2145d.o #obj-m+= ov8858.o #obj-m+= ov13850.o #obj-m+= imx214.o #obj-m+= ov8858_4lane.o #obj-m+= sp5409.o #obj-m+= s5k5e2yx.o #obj-m+= ov2710_mipi.o #obj-m+= siv121d.o #obj-m+= ov2710_mipi.o...

    twitter-bootstrap-v2.1.1-0-gc52368d.zip

    这个压缩包 "twitter-bootstrap-v2.1.1-0-gc52368d.zip" 包含的是Twitter Bootstrap的2.1.1版本,这是一个在Git版本控制下(标识为gc52368d)的特定修订版。Bootstrap自2.0版本起就引入了显著的改进和功能,而2.1.1...

    英特尔 支持嵌入式计算的英特尔945G和945GC高速芯片组产品简介.pdf

    此外,英特尔945G和945GC高速芯片组支持超线程技术(HT技术)的英特尔奔腾4处理器和英特尔赛扬D处理器,这些处理器均支持英特尔64位架构,使得整个平台不仅具备可扩展性能,还为嵌入式计算应用提供了理想的高性价比...

    艾讯宏达 SYS71838 945GC工控长卡.pdf

    1. 芯片组与处理器兼容性:SYS71838使用了Intel 945GC+ICH7+FWH芯片组,支持LGA775接口的Intel Core 2 Duo、Pentium Dual-Core、Pentium EE、Pentium D、Pentium 4、Celeron D系列处理器,支持前端总线频率为533MHz...

    华硕P5GC-MX1333主板BIOS 0312版

    【华硕P5GC-MX】是华硕的一款基于Intel G31+ICH7芯片组的主板,支持LGA775插槽的Intel Pentium 4、Core 2 Duo、Pentium D和Celeron系列处理器。它的主要特性可能包括: 1. **双通道DDR2内存**:支持DDR2 800/667...

    运营商5G认证考核测试2021.docx

    SOC2.0样机里CGW网元包含OMU和()虚拟机    A、IPU    B、SPU    C、VPU    D、SDU  答案C    5GC中负责融合计费的网元是    A、 OCS    B、CG    C、CHF    D、PCF  答案C  ...

    r40_tinav2.1_最终验证通过_使用CB-S来验证OV5640有横条纹fpscamera+SPI2.0成功_20171114_1443没有外层目录.7z

    r40_tinav2.1_最终验证通过_使用CB-S来验证OV5640有横条纹fpscamera+SPI2.0成功_20171114_1443没有外层目录.7z 开发板:CB-S 1、(可选修改/调试技巧:) 除了ov5640.c之外,其它的驱动都不编译,节省编译时间!...

    二级建造师《机电工程管理与实务》模拟考试II卷(附答案).pdf

    5. “181916()17()()()2GA1GC1A3()4()()20()212223C.D.E.A.B.C.D.E.A.B.C.D.E.A.B.C.D.E.A.B.C.”这部分内容可能是关于项目管理、施工组织设计、设备安装、质量检验、安全规范等方面的问题。 6. 部分内容如“80%”...

    Java复习题答案.pdf

    D、当调用 System.gc() 方法时。 27、Java 中的字符串类是哪个?(D ) A、StringBuffer B、StringBuilder C、StringPool D、String 28、Java 中的 Swing 库主要用于创建什么?(B ) A、控制台应用程序 B、图形用户...

    matlab加噪声代码-GPz:GPz2.0:不确定和不完整数据的异方差高斯过程

    2.0 不确定和不完整数据的异方高斯过程 介绍 这是所描述的稀疏异方差高斯过程的matlab实现。 数据集被认为是由输入组成和目标输出,其中n是数据集中的样本数,d是输入的维数。 目标由输入函数生成 加上附加噪声: 。...

    oracle 培训

    从提供的部分内容中可以看出,文档是“Oracle Database 11g: Administration Workshop II Volume I•Student Guide D50079GC20 Edition 2.0 September 2010 D62543”,这是一本针对Oracle Database 11g第二部分内容...

    hm1375_tinav2.1验证通过_增加设备ID的读取显示_20170825_1333没有外层目录.7z

    #obj-m+= gc2145d.o #obj-m+= ov8858.o #obj-m+= ov13850.o #obj-m+= imx214.o #obj-m+= ov8858_4lane.o #obj-m+= sp5409.o #obj-m+= s5k5e2yx.o #obj-m+= ov2710_mipi.o #obj-m+= siv121d.o #obj-m+= ov2710_mipi.o...

    sun java 认证题.pdf

    Memory is reclaimed by calling Runtime.gc().**:通过调用`Runtime.gc()`来回收内存。 - **B. Object** **结论:**正确答案是**A**。虽然调用`Runtime.gc()`可以请求Java虚拟机尝试执行垃圾回收,但是否立即执行...

    Oracle 11g OCP_Z052资料

    **Oracle Database 11g: Administration Workshop I Volume I • Student Guide D50102GC20 Edition 2.0 August 2010 D62541** 这部分内容揭示了文档的具体名称和版本信息。文档名为《Oracle Database 11g: ...

Global site tag (gtag.js) - Google Analytics