我正在阅读关于真实世界OCaml中的GC,第21章的文章,并有一些关于次要堆的问题。
上面写着:
小堆是一个连续的虚拟内存块,通常只有几兆字节,这样就可以快速扫描它。

运行时将小堆的边界存储在两个指针中,以分隔堆区域的开始和结束(caml_young_start和caml_young_end,但为了简洁起见,我们将删除caml_young前缀)。基是系统malloc返回的内存地址,并且start是对齐与距基最近的单词边界对齐的,以便更容易地存储OCaml值。 在新的小堆中,限制等于开始,当前ptr将等于结束。ptr会随着块的分配而减少,直到达到极限为止,这时会触发一个次要的垃圾收集。 你可能会想,为什么限制是必需的,因为它似乎总是平等的开始。这是因为运行时调度小堆收集的最简单方法是将限制设置为相等的。在此之后,下一次分配将永远没有足够的空间,并且总是会触发垃圾收集。早期收集有各种内部原因,例如处理挂起的UNIX信号,它们通常与应用程序代码无关。
Q1:小堆与 base的关系
基本上,运行时将尝试使用system将内存块(例如,大小为8MB)分配为小堆。
那么malloc返回的地址是基本地址吗?
Q2: base 与 start的关系
start is aligned against the next nearest word boundary from base是什么意思?
这里对齐的术语是否意味着开始寻找下一个mods 4等于0的内存地址?
我认为malloc无论如何都会强制对齐,即总是返回mod 4=0的地址。
limit Q3:我们使用启动,而使用Q3
它解释了极限可以用来调度GC。
但是,那么开始有什么用呢?
发布于 2014-06-15 18:15:29
您可以在minor_gc.c中找到您询问的代码。(我不是OCaml GC高手--我不得不四处寻找代码。)
下面是一个简化的版本:
void caml_set_minor_heap_size (asize_t size)
{
char *new_heap;
void *new_heap_base;
if (caml_young_ptr != caml_young_end) caml_minor_collection ();
new_heap = caml_aligned_malloc(size, 0, &new_heap_base);
if (new_heap == NULL) caml_raise_out_of_memory();
if (caml_page_table_add(In_young, new_heap, new_heap + size) != 0)
caml_raise_out_of_memory();
if (caml_young_start != NULL){
caml_page_table_remove(In_young, caml_young_start, caml_young_end);
free (caml_young_base);
}
caml_young_base = new_heap_base;
caml_young_start = new_heap;
caml_young_end = new_heap + size;
caml_young_limit = caml_young_start;
caml_young_ptr = caml_young_end;
caml_minor_heap_size = size;
reset_table (&caml_ref_table);
reset_table (&caml_weak_ref_table);
}基是malloc返回的块的实际起始地址。稍后,当您想释放块时(如果您想要更改小堆的大小,则需要这样做)。据我所知,这个基地没有其他用途。
开始是一个对齐版本的基。我正在查看的代码(OCaml 4.01.0)与页面边界(4KB)对齐。Malloc只对齐原始数据类型(8字节左右)。
您需要开始重新设置限制后,您已经人为地修改它,如您的摘录的最后一段所述。
https://stackoverflow.com/questions/24231862
复制相似问题