提问人:lucocozz 提问时间:3/27/2023 最后编辑:lucocozz 更新时间:5/20/2023 访问量:126
为什么使用“munmap()”后页面回收仍然存在?
Why pages reclaims still present after using `munmap()`?
问:
对于一个研究项目,我必须编写 和 使用 和 的重新实现。malloc()
free()
mmap()
munmap()
我在最后一个 Ubuntu 上运行。在我的测试中,我使用命令 (from),它向我展示了有关我的程序的大量信息,包括内存。以下是一些示例:time -v
/usr/bin/time
因此,我们可以看到哪个对应于回收页数根据我们的使用情况而变化,但特别是如果我们在回收页数返回到其初始数量后使用,则我的重新实现并非如此:Minor page faults
free()
malloc()
以下是我的代码片段,用于可视化我的工作。
在我的 :malloc()
static t_page *__alloc_page(size_t size)
{
struct rlimit limit;
t_page *page;
getrlimit(RLIMIT_AS, &limit);
if (size > limit.rlim_max)
return (NULL);
page = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (page == MAP_FAILED)
return (NULL);
ft_bzero(page, sizeof(t_page));
page->size = size;
page->used_size = sizeof(t_page);
return (page);
}
在我的 :free()
static void __free_page(t_page *page)
{
t_binding *binder = __get_binder(page);
binder->count--;
if (binder->pages == page)
binder->pages = page->next;
if (page->prev != NULL)
page->prev->next = page->next;
if (page->next != NULL)
page->next->prev = page->prev;
if (munmap(page, page->size) == -1)
ft_putstr("free(): munmap error\n");
}
作为信息,我的大小始终是 () 的倍数。getpagesize()
N * getpagesize()
以下是我进行测试的方式
首先,我将我的文件等编译成一个动态库()。
然后我用下面的 main 构建了两个二进制文件。一个是用我的 malloc 编译的,另一个是用 libc 编译的。malloc.c
free.c
libmalloc.so
clang main.c -o libc_malloc
clang main.c -D LIBMALLOC libmalloc.so -o my_malloc
#ifdef LIBMALLOC
# include "../includes/malloc.h"
#else
# include <stdlib.h>
#endif
int main(void)
{
int i;
char *addr;
i = 0;
while (i < 1024)
{
addr = (char*)malloc(1024);
addr[0] = 42;
free(addr);
i++;
}
return (0);
}
我还有一个脚本,允许我使用名为run.sh
#!/bin/sh
export LD_LIBRARY_PATH="."
export LD_PRELOAD="`pwd`/libmalloc.so"
$@
最后,我像这样运行我的两个二进制文件:time -v
/usr/bin/time -v ./libc_malloc
./run.sh /usr/bin/time -v ./my_malloc
如何以极简主义的方式复制
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int i;
char *addr;
i = 0;
#ifdef _MMAP_
printf("mmap\n");
#else
printf("malloc\n");
#endif
while (i < 1024)
{
#ifdef _MMAP_
addr = mmap(NULL, 4 * getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#else
addr = malloc(4 * getpagesize());
#endif
addr[0] = 42;
#ifdef _MMAP_
munmap(addr, 4 * getpagesize());
#else
free(addr);
#endif
i++;
}
return (0);
}
将上面的这个主要内容复制到一个文件 () 中。
创建两个二进制文件,如下所示:main.c
clang main.c -o using_malloc
clang -D _MMAP_ main.c -o using_mmap
然后使用以下命令运行它们:time -v
/usr/bin/time -v ./using_malloc
/usr/bin/time -v ./using_mmap
我试过什么
在互联网上搜索时,我遇到了这篇文章,它的问题与我的完全相同:使用 munmap
时页面回收率更高,
但建议的解决方案不起作用(我不能使用它)。
我不被允许使用类似或两者兼而有之的功能......
无论如何,我都尝试了它们,看看它们是否能解决我的问题,但没有成功。
我还运行了别人的项目。他工作得很好,而我们似乎在做同样的事情。
我错过了什么吗?posix_madvise()
msync()
答:
我找到了我的问题。在我的主力中,我不断地一个接一个地执行 malloc() 和 free()。当系统执行时,它会尝试通过不立即删除分配的页面来优化,以便以后重用它。但是,这仍会导致在后续调用 时创建新页面。munmap()
mmap()
mmap()
要解决此问题,需要保留一个剩余的页面,以便不会在循环中调用该页面。free()
munmap()
我的解释不是很清楚,请随时提供更多细节。
评论
RSS
posix_madvise/madvise/msync
malloc
free
main