Memory management 如何在一个进程中将一个堆拆分为多个堆?

Memory management 如何在一个进程中将一个堆拆分为多个堆?,memory-management,garbage-collection,language-agnostic,heap,Memory Management,Garbage Collection,Language Agnostic,Heap,现在哪些生态系统允许创建多个堆 AppDomains不创建新堆(所有域仍有一个堆)。那么,在单个进程中启动几个不同的GC需要做什么呢 需要创建哪些语法原语?运行时应该如何支持该原语 现在哪些生态系统允许创建多个堆 一个显而易见的答案是“C++”(如果你不认为语言本身就是一个“生态系统”),就可以随意填充周围的东西,如果你不认为它是一个“生态系统”。 C++允许您沿几个不同的轴指定堆。一种是根据对象的类型——您可以通过重载该类型的operator new和operator delete来

现在哪些生态系统允许创建多个堆

AppDomains不创建新堆(所有域仍有一个堆)。那么,在单个进程中启动几个不同的GC需要做什么呢

需要创建哪些语法原语?运行时应该如何支持该原语

现在哪些生态系统允许创建多个堆

一个显而易见的答案是“C++”(如果你不认为语言本身就是一个“生态系统”),就可以随意填充周围的东西,如果你不认为它是一个“生态系统”。 C++允许您沿几个不同的轴指定堆。一种是根据对象的类型——您可以通过重载该类型的
operator new
operator delete
来指定特定类型的分配:

class Foo { 
    static void *operator new(size_t size);
    static void operator delete(void *block, size_t size);
};
然后由您将这些堆管理函数连接到实际的内存源。您可以通过
::operator new
进行分配,或者(例如)直接进入操作系统,例如在Windows上使用
GlobalAlloc
VirtualAlloc
,在类UNIX系统上使用
sbrk
,或者在裸机嵌入式系统上使用预先指定的内存块

沿着一个稍微不同的轴,C++标准库中的所有容器通过分配器类分配和释放内存。任何特定集合的分配器都指定为模板参数,因此(例如)

std::vector
的声明如下所示:

template <class T, class Alloc=std::allocator<T>>
class vector {
    // ...
};
模板
类向量{
// ...
};
这允许您指定将用于分配该集合中的对象的堆。与
operator new
operator delete
一样,这实际上只指定集合分配和释放内存的接口——这取决于您将其连接到实际管理堆的代码

垃圾收集 就垃圾收集而言:我个人觉得它很烦人,建议不要将其作为一般规则使用。问题是,虽然它可以(至少从一个角度)修复内存管理中的某些类型的问题,但它对其他资源的管理毫无帮助(不幸的是),而且我还没有见过任何类似于文件句柄、网络套接字、数据库连接等的跟踪收集器。RAII提供了一种处理资源管理的统一方法

<>你说,如果你真的坚持使用GC,C++也支持它。在C++11之前,GC在实践层面上是完全可用的,但在一些模糊的情况下会导致技术上未定义的行为,例如:

  • 将指针存储在文件中并读回,或
  • 修改指针的位,然后取消该修改
…然后获取重新构造的指针并取消对它的引用。显然,虽然CPU看不到指针,但指向的内存块符合GC的条件,因此后来的取消引用导致了问题。C++11定义了这些情况,并添加了一些库调用(例如,
declare\u reachable
undeclare\u reachable
)来处理它们(例如,如果调用
decare\u reachable(block);
,则
block
不符合收集条件,无论指向它的指针是否可见)。因此,如果您想使用C++来使用GC,则可以完全指定定义行为的界限。唯一的问题是基本上没有任何代码调用
declare\u reachable
和/或
undeclare\u reachable
,因此在实际使用中,它们可能没有什么帮助(但指针滑动和/或文件中的存储非常罕见,这不太可能造成真正的问题)

对于一个实际的例子,您可能想看看(如果您还没有)