假设我有一个内存中的 b 树(不是 b+ 树),其节点声明如下:
struct node
{
int* keys;
struct node** children;
int currentNumOfKeys;
char isLeaf;
}
我读过使用
mmap()
,人们可以将内存区域映射到文件中并存储数据,忘记所有关于持久性的事情,并且下次加载程序时,所有指针都是有效的!假设您要么将文件映射到完全相同的起始地址,要么使用指针的相对偏移量!
现在,如果我想利用这一点,很明显,中继获取完全相同的地址是不可移植的,因此: 假设我有一棵树,它的大小从 0 字节开始,但可能会增长到 100 GB 或更大;
mmap
处理文件就足够了吗?malloc()
进行分配,它只会给我操作系统想要的任何地址;如何从映射区域初始化结构对象?我想要这样的东西:
1-初始化映射区域中树的第一个节点
2- 将我的更改为struct node** children
> 这样我就可以存储子节点从该根节点开始的偏移量int children[MAX_DEGREE]
3-初始化并存储映射区域中的下一个节点,以某种方式在下次程序启动时映射文件重新创建树而无需对其进行排序
在每一步中,我都想避免使用交换文件来弥补内存不足或将数据复制到磁盘(显然除了映射文件之外)。
- 如何将这样一棵100GB大小的树映射到8GB大小的内存中?
处理文件就足够了吗?mmap
假设您的系统上有 8 GiB 的物理内存,支持更大的地址空间,操作系统将维护有关虚拟地址空间的信息,并将部分虚拟内存映射到物理内存,并随时更改该映射根据需要计时。除了调用操作系统例程来映射内存之外,您无需为此执行任何特殊操作。
- 操作系统如何处理这个大小?它会使用请求分页并仅在请求后加载文件的每个 4064 字节并删除第一页以便为新页面腾出空间吗?
操作系统会根据需要映射物理页。页面大小不会是 4064 字节,因为它不是 2 的幂,但它可能是 4096 字节。当选择要取消映射的页面时,操作系统不一定会选择第一个页面;它可能会维护一些有关页面最近使用情况的信息,并尝试取消映射一段时间未使用的页面。因此哪些页面未映射可能取决于程序中的使用模式。
- 如何指示操作系统一次加载多个页面以避免页面错误?
操作系统具有复杂且经过时间考验的内存管理算法,并且可能会与系统上的其他进程平衡地分配进程物理内存。通常,普通用户级程序无法指定应为它们分配比平常共享更多的内存。
- 当我以正常方式使用内存时,使用
进行分配,它只会给我操作系统想要的任何地址;如何从映射区域初始化结构对象?malloc()
这个问题不清楚。如果要将数据从手动映射的区域复制到用
malloc
分配的内存中,则必须相应地调整指针或使用偏移量而不是指针。