ตัวอย่างที่เรียกใช้น้อยที่สุด
  การเรียกระบบ brk () ทำอะไรได้บ้าง?
ขอเคอร์เนลให้คุณอ่านและเขียนหน่วยความจำต่อเนื่องที่เรียกว่าฮีป
ถ้าคุณไม่ถามมันอาจเป็นการแยกคุณออก
โดยไม่ต้องbrk:
#define _GNU_SOURCE
#include <unistd.h>
int main(void) {
    /* Get the first address beyond the end of the heap. */
    void *b = sbrk(0);
    int *p = (int *)b;
    /* May segfault because it is outside of the heap. */
    *p = 1;
    return 0;
}
ด้วยbrk:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
    void *b = sbrk(0);
    int *p = (int *)b;
    /* Move it 2 ints forward */
    brk(p + 2);
    /* Use the ints. */
    *p = 1;
    *(p + 1) = 2;
    assert(*p == 1);
    assert(*(p + 1) == 2);
    /* Deallocate back. */
    brk(b);
    return 0;
}
GitHub ต้นน้ำ
ด้านบนอาจไม่ตีหน้าใหม่และไม่แยก segfault แม้จะไม่มีbrkดังนั้นนี่เป็นเวอร์ชั่นที่ก้าวร้าวมากขึ้นซึ่งจัดสรร 16MiB และมีแนวโน้มที่จะ segfault โดยไม่ต้องbrk:
#define _GNU_SOURCE
#include <assert.h>
#include <unistd.h>
int main(void) {
    void *b;
    char *p, *end;
    b = sbrk(0);
    p = (char *)b;
    end = p + 0x1000000;
    brk(end);
    while (p < end) {
        *(p++) = 1;
    }
    brk(b);
    return 0;
}
ทดสอบบน Ubuntu 18.04
การสร้างภาพพื้นที่ที่อยู่เสมือน
ก่อนbrk:
+------+ <-- Heap Start == Heap End
หลังbrk(p + 2):
+------+ <-- Heap Start + 2 * sizof(int) == Heap End 
|      |
| You can now write your ints
| in this memory area.
|      |
+------+ <-- Heap Start
หลังbrk(b):
+------+ <-- Heap Start == Heap End
เพื่อให้เข้าใจถึงช่องว่างที่อยู่ได้ดีขึ้นคุณควรทำความคุ้นเคยกับการเพจ: การเพจจิ้ง x86 ทำงานอย่างไร? .
ทำไมเราต้องการทั้งสองอย่างbrkและsbrk?
brkสามารถนำไปใช้กับการsbrkคำนวณ + ออฟเซ็ตซึ่งทั้งสองมีอยู่เพื่อความสะดวก
ในส่วนแบ็คเอนด์เคอร์เนล Linux v5.0 มีการเรียกระบบเดียวbrkที่ใช้ในการดำเนินการทั้งสองอย่าง: https://github.com/torvalds/linux/blob/v5.0/arch/x86/entry/syscalls/syscall_64 tbl # L23
12  common  brk         __x64_sys_brk
brkPOSIX คืออะไร
brkเคยเป็น POSIX แต่มันถูกลบใน POSIX 2001 ดังนั้นจึงจำเป็นต้อง_GNU_SOURCEเข้าถึง glibc wrapper
การลบนี้น่าจะเกิดจากการแนะนำmmapซึ่งเป็น superset ที่อนุญาตให้มีการจัดสรรหลายช่วงและตัวเลือกการจัดสรรเพิ่มเติม
ฉันคิดว่าไม่มีกรณีที่ถูกต้องที่คุณควรใช้brkแทนmallocหรือmmapทุกวันนี้
brk VS malloc
brkmallocเป็นหนึ่งในความเป็นไปได้ของการใช้เก่า
mmapเป็นรุ่นใหม่ที่มีประสิทธิภาพมากขึ้น stricly กลไกซึ่งมีแนวโน้มที่ทุกระบบ POSIX mallocใช้อยู่ในปัจจุบันในการดำเนินการ นี่คือที่ทำงานได้น้อยที่สุดmmapเช่นการจัดสรรหน่วยความจำ
ฉันสามารถผสมbrkและ malloc ได้หรือไม่?
หากคุณmallocนำไปใช้กับbrkฉันไม่ทราบว่าวิธีการที่ไม่สามารถระเบิดสิ่งต่าง ๆ เนื่องจากbrkจัดการหน่วยความจำช่วงเดียวเท่านั้น
อย่างไรก็ตามฉันไม่พบอะไรเกี่ยวกับเรื่องนี้ในเอกสาร glibc เช่น:
สิ่งที่อาจจะเป็นเพียงแค่ทำงานที่นั่นผมคิดว่าตั้งแต่มีแนวโน้มที่จะใช้สำหรับการmmapmalloc
ดูสิ่งนี้ด้วย:
ข้อมูลเพิ่มเติม
ภายในเคอร์เนลจะตัดสินว่ากระบวนการสามารถมีหน่วยความจำขนาดนั้นหรือไม่และหน้าหน่วยความจำ earmarks สำหรับการใช้งานนั้น
สิ่งนี้อธิบายถึงการเปรียบเทียบสแต็กกับฮีป: ฟังก์ชันของคำแนะนำการกด / ป๊อปที่ใช้กับการลงทะเบียนในแอสเซมบลี x86 คืออะไร