简体   繁体   English

brk(),sbrk()和realloc()函数之间的区别

[英]Difference between brk() , sbrk() and realloc() functions

我知道函数brk(),sbrk()用于重新分配内存。但它们与realloc()函数有什么不同?。给我编码示例。

brk and sbrk are system calls (implemented in the kernel) while malloc , free , realloc are library functions in user space. brksbrk是系统调用(在内核中实现),而mallocfreerealloc是用户空间中的库函数。 So the malloc etc functions use brk and sbrk internally but provide additional functionality (see man(2) for more details about brk and man(3) for more details about malloc .). 因此malloc等函数在内部使用brksbrk但提供了额外的功能(有关malloc更多详细信息,请参阅man(2)以获取有关brkman(3)的更多详细信息。)。

brk only tells the kernel how much memory your program wants to use, by giving the the kernel a pointer to the largest virtual memory location that your program may use. brk只通过向内核提供指向程序可能使用的最大虚拟内存位置的指针,告诉内核程序想要使用多少内存。 But you only have exactly one big chunk of memory. 但是你只有大块内存。

malloc helps you to subdivide this huge block of memory into smaller parts. malloc帮助您将这个巨大的内存块细分为更小的部分。

Example code doesn't make much sense here, because brk and malloc work on different levels. 示例代码在这里没有多大意义,因为brkmalloc在不同的级别上工作。 But you could think how you would implement a very simple (and non-thread-safe) version of malloc and free and where you would use brk there: 但你可以想一想如何实现一个非常简单(和非线程安全)的mallocfree版本以及你在那里使用brk地方:

  1. The basic data structure for our primitive malloc is a linked list. 我们的原始malloc的基本数据结构是一个链表。
  2. Each list element in the list contains of: 列表中的每个列表元素包含:
    1. The size of the block 块的大小
    2. A pointer to the next element 指向下一个元素的指针
    3. A flag if the block is in use 如果块正在使用中的标志
    4. A flag if it is the last element 如果它是最后一个元素的标志
    5. An array of bytes with the given size 具有给定大小的字节数组
  3. In each call, malloc goes through the list and checks for each block 在每次调用中,malloc都会遍历列表并检查每个块
    1. If the block is flagged as "not in use" 如果该块被标记为“未使用”
    2. If the size field of the list element is at most as big as the size needed 如果list元素的size字段最多与所需大小一样大
  4. If malloc finds such a block, it will: 如果malloc找到这样的块,它将:
    1. Mark the list element as used 将列表元素标记为已使用
    2. Adjust the size field in the list element 调整list元素中的size字段
    3. If there is enough space then add a list element after the element, pointing to the next element in the list (if applicable) 如果有足够的空间,则在元素后面添加一个list元素,指向列表中的下一个元素(如果适用)
    4. Return a pointer to the byte array of the list element it found 返回指向它找到的列表元素的字节数组的指针
  5. If malloc doesn't find such a list element, it will 如果malloc找不到这样的列表元素,它就会
    1. Call brk to increase the usable memory we got from the kernel 调用brk来增加我们从内核获得的可用内存
    2. Add a new element to the end of the list, set the size to the desired size 将新元素添加到列表末尾,将大小设置为所需大小
    3. Mark this element as in use AND as the last element 将此元素标记为使用AND并作为最后一个元素
    4. Return a pointer to the byte array of the newly created list entry 返回指向新创建的列表条目的字节数组的指针

And as @BasileStarynkevitch remarked in his comment, as an alternative to brk you could also use mmap (with fd=-1 and flags=MAP_PRIVATE|MAP_ANONYMOUS ) to reserve a single block of memory backed by the swap file. 正如@BasileStarynkevitch在评论中所说,作为brk的替代方法,您还可以使用mmap (使用fd=-1flags=MAP_PRIVATE|MAP_ANONYMOUS )来保留由交换文件支持的单个内存块。 For details about mmap see man(2) . 有关mmap的详细信息,请参阅man(2)

At the OS level (in the Unix model, at least), your program has one big region of memory for program text, initialized and uninitialized data, and the "heap", for dynamically-allocated data. 在操作系统级别(至少在Unix模型中),程序文本,初始化和未初始化数据以及动态分配数据的“堆”都有一个很大的内存区域。 (The stack is separate.) You can adjust the size of that region using brk and sbrk , but you can't rearrange it, and it's always contiguous. (堆栈是独立的。)您可以使用brksbrk调整该区域的大小,但不能重新排列它,它总是连续的。 The vast majority of programs that do dynamic memory allocation require something more flexible. 绝大多数进行动态内存分配的程序需要更灵活的东西。

malloc , free , and realloc are C library functions that give you something more flexible. mallocfreerealloc是C库函数,可以为您提供更灵活的功能。 Underneath, they get memory from the OS by calling brk and/or sbrk , but then they do extra processing to let you allocate (a) any number of chunks of (b) different sizes and which you can (c) individually return to the pool when you're done with them and incidentally (d) resize. 在下面,他们通过调用brk和/或sbrk从操作系统获取内存,但随后他们做了额外的处理,让你分配(a)任意数量的(b)不同大小的块,你可以(c)单独返回到当你完成它们并且偶然地(d)重新调整大小时。

But when you return memory to the pool with free , it generally just goes back into the pool that future calls to malloc by your program will draw from; 但是当你以free将内存返回到池中时,它通常只会回到池中,以后您的程序将来自malloc的调用将从中抽取; memory is generally not given back to the OS. 内存通常不会返回给操作系统。

(Sorry for not providing any example code; I don't have time for that just now.) (很抱歉没有提供任何示例代码;我刚才没有时间。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM