`

C++下垃圾回收器的实现

阅读更多

C++下的垃圾回收机制可能会在下个版本加入,我只是想通过实例,分析垃圾回收器的内部机制,深入了解以后,在以后
的项目中,就可以对是否需要垃圾回收功能做出准确的判断。

它是否影响性能,能影响多少,回收的代价等等问题就会显得更加明确。

对C++下垃圾回收的讨论很多,有兴趣可以看看这里这里。至于实现,惠普的垃圾回收器是一个产品化的开源项目,而且已经被很多项目使用。但是他的具体实现总是让人感觉不是很可靠。云风是一个简单的回收器,有人对其源码进行研究,有兴趣可以看这里,它没有内存紧缩功能。

首先,说说垃圾回收的目标,也就是需求。
1. 不能有内存泄漏(最基本的要求)。
2. 能自动回收无用内存(当然需要解决循环引用问题)。
3. 能整理内存(内存紧缩),程序运行时间长了,总会有小块内存无法被重复使用。

先说说前两条需求,程序中的所有已分配内存都应该有其对应的指针指向它,如果一块内存没有任何指针指向它,那么我们说这块内存被泄漏了(这里内存泄漏的定义和Java不太一样)。

简单的表述就是无用对象且不可达。

什么叫可达?可达表示从哪里为起点可达?这里要引出一个叫根集的概念:在程序运行的任意状态,寄存器(考虑多核CPU在多线程下),程序栈,和静态数据段中所有的指针的集合叫根集。
所以可达指的是这块内存从根集出发,可以找到一个指向它的指针,不可达就是找不到。

要实现垃圾回收器,首先要能在程序的任意状态,找到根集。其次是要能管理所有堆上的内存。当从根集扫描发现一块不可达内存时,这块内存就应该被收集。

注意上图:黄色的指针表示它是根集,红色的指针则不是根集。
要回收内存,首先要知道内存的地址,所以上图中4块内存的地址是必须知道的。

看看要回收内存,需要知道那些信息吧:

根集和内存块集。收集前,先从根集顺着黑色的箭头开始扫描,对所以扫描到的内存块做个标记,然后从内存块集中检查所有内存块,如果被做了标记,就保留,如果没有做标记,就收集。

怎么得到根集呢?对于像Java,C#之类的语言,它的指针是受到虚拟机或者Framework控制的,但是在C++中,原生的指针(raw pointer)是不受控制的,而且Scott Meyers([More] Effective C++)的作者,
Andrew Koenig夫妇(C++ 沉思录)的作者,这些大牛们多次劝告,不要使用原生指针。

所以以前有auto_ptr, 现在有shared_ptr问世。为了得到根集,我也将原生指针进行包装,只不过不用于所有权管理,也不用于引用计数,而是用于得到根集。
首先看看指针的定义:

class pointer_base
{
public:
    
virtual ~pointer_base()
    
{}

    
virtual void* get_ptr() const = 0;
    
virtual void set_ptr(const void *p) = 0;
}
;

template 
<class _T>
class pointer : public pointer_base
{
public:
    pointer()
        : p(NULL)
    
{
        

gc_register(*this);
    }

    pointer(_T
* t)
        : p(t)
    
{
        
gc_register(*this);
    }

    _T
& operator*() const
    
{
        
return *p;
    }


    _T
* operator->() const
    
{
        
return p;
    }

private:
    _T 
*p;
}
;

 

注意pointer的构造函数,它将自己注册到根集中去。

再看看根集:

std::list<pointer_base *> gc_root_set;


gc_register 函数也就是做了一个push_back。

有人会问,那要是出现这种情况:

class A
{
    
//
}
;

class B
{
    pointer
<A> pA;
}
;

void main()
{
    B
* pB = new B();
}

 

那不是pB->pA在堆上吗?不应该属于根集呀。
这个问题就要和内存块管理扯上关系啦,下篇再说
整个垃圾回收器已经写完并简单的测试代码在这里,有兴趣可以看看并测试。

分享到:
评论

相关推荐

    c++ 垃圾回收机制

    2. **Herbert Schildt对C++垃圾回收机制的实现.mht** - Herbert Schildt是一位知名的C++编程书籍作者,他可能提出了自己对于C++中垃圾回收的见解或实现。这个文件可能包含了Schildt对于如何在C++中实现自动内存管理...

    C++实现垃圾回收器

    然而,为了在C++中实现类似的功能,我们可以构建自定义的垃圾回收器。本话题将深入探讨如何用C++实现一个简单的单线程垃圾回收器。 首先,理解垃圾回收的基本原理至关重要。垃圾回收器的主要任务是识别那些已经不再...

    简单c++垃圾回收器

    为了解决这个问题,我们可以设计一个简单的C++垃圾回收器(Garbage Collector)。这个回收器的目的是自动追踪和释放不再使用的堆内存,以防止内存泄漏。 内存泄漏是指程序分配了内存但未能正确地释放它。长期的内存...

    C++垃圾回收器linux版本

    这个项目包含两个部分:`gclinux单线程`和`gclinux多线程`,分别对应于在Linux环境下单线程和多线程环境下的C++垃圾回收器实现。理解这两个组件,我们需要探讨以下几个关键知识点: 1. **内存管理**:C++的标准库并...

    用模板实现的C++垃圾回收器.zip

    "用模板实现的C++垃圾回收器.zip"这个项目就是针对这个问题提供的一种解决方案。 首先,让我们深入了解一下C++模板。模板是C++中的一个强大特性,它允许我们创建泛型代码,即可以应用于多种数据类型的代码。模板...

    C++实现的垃圾回收管理类

    深入研究这些源码,可以学习到如何在C++中实现一个自定义的垃圾回收机制,以及如何在实际项目中有效地管理动态内存,避免内存泄漏。这样的实践对于提升C++编程技能和理解底层内存管理原理非常有帮助。

    AutoGC简单的C++垃圾回收器,基于多线程。

    AutoGC是一个针对C++编程语言设计的简单垃圾回收器,主要特点是它采用了多线程技术以及资源获取即初始化(RAII)原则。垃圾回收(GC)通常在动态内存管理中用于自动追踪并释放不再使用的内存,以防止内存泄漏。在C++...

    gc.zip_unix c++_垃圾回收器

    本文将详细探讨如何在Unix环境下用C++来实现一个垃圾回收器。 首先,我们需要理解垃圾回收的基本概念。垃圾是程序中不再使用的内存块。在C++中,程序员负责动态内存的分配和释放,但如果没有正确地释放内存,就会...

    c++垃圾回收源代码

    3. **垃圾回收器设计**:设计一个垃圾回收器需要考虑如何追踪对象的可达性,确定哪些对象可以被安全地回收。这可能包括跟踪对象间的引用关系,使用标记-清除、复制、标记-整理或分代等算法。 4. **自定义new和...

    java高级之垃圾回收机制

    垃圾回收可以在不同的条件下被触发: 1. **系统调用**:开发者可以通过调用`System.gc()`显式请求垃圾回收,但这并不是推荐的做法,因为JVM可能会忽略此请求。 2. **内存不足**:当JVM检测到堆内存不足时,会自动...

    C++垃圾回收站源代码!!

    本篇将详细解析标题所提及的"C++垃圾回收站"源代码。 首先,理解垃圾回收的基本原理。垃圾回收是一种自动的内存管理技术,它的主要任务是追踪和回收那些不再被程序引用的对象所占用的内存。在C++中实现垃圾回收,...

    java垃圾回收机制

    ### Java垃圾回收机制详解 #### 一、垃圾收集的意义及背景 在计算机编程领域,特别是对于内存管理方面,Java提供了一种与C++等其他语言截然不同的方式。在C++中,对象所占用的内存资源需要程序员手动管理,这意味...

    C++实现自动内存回收

    在C++中,虽然没有内置的垃圾回收机制,但可以通过特定的设计模式和库来实现类似的功能。 《The Art of C++》这本书探讨了如何在C++中实现自动内存回收,特别提到了一些可能存在的问题和解决方案。在这个话题中,...

    著名的C_C++垃圾回收站.zip

    标题中的“著名的C/C++垃圾回收站”暗示了我们讨论的主题是关于C++编程语言中的内存管理和垃圾回收机制。在C++中,垃圾回收通常不被内置支持,因为程序员需要手动管理内存,通过new和delete操作符来分配和释放内存。...

    C++引用计数设计与分析(解决垃圾回收问题).docx

    C++是一种静态类型、编译式、通用的、大小写敏感的、不仅...通过结合使用构造函数、析构函数、智能指针和引用计数,C++程序员可以在没有内置垃圾回收机制的情况下,更好地控制内存的生命周期,从而降低内存泄漏的风险。

    VC6.0下的垃圾回收实现代码

    综上所述,"VC6.0下的垃圾回收实现代码"提供了实现自定义垃圾回收机制的方法,这对于理解内存管理、提高程序的健壮性和性能都非常重要。通过阅读和分析提供的代码,开发者可以学习到如何在没有内置GC支持的语言或...

    灵巧指针与垃圾回收(Java、C#、C++)

    【灵巧指针与垃圾回收】是编程语言中关于内存管理的一个重要概念,尤其是在Java、C#和C++之间有着显著的区别。Java和C#都内置了垃圾回收机制,允许程序员在分配内存后无需手动释放,由系统自动进行垃圾回收。这种...

    cpp-从blink里剥离的垃圾回收组件能让c拥有java一样的自动垃圾回收机制

    在Java中,垃圾回收器会定期检查内存中哪些对象不再被引用,然后回收这些内存供后续使用。在C++中,通常需要程序员自己负责内存分配和释放,这可能导致内存泄漏或悬挂指针等问题,而引入GC机制则可以解决这些问题。 ...

    关于C++为什么不加入垃圾回收机制解析

    8. 用户可控性:C++允许程序员根据具体应用场景选择最适合的内存管理策略,这包括在某些情况下使用垃圾回收库,如Boost.GIL(Garbage-Independent Library),或者自定义内存管理系统。 综上所述,C++没有内置垃圾...

Global site tag (gtag.js) - Google Analytics