当前位置: 首页 > 面试题库 >

mmap或malloc是否分配RAM?

洪胤
2023-03-14
问题内容

我知道这可能是一个愚蠢的问题,但是我已经寻找了一段时间,找不到确切的答案。如果我使用mmapmalloc(在Linux机器上的C语言中),是否有人在RAM中分配空间?例如,如果我有2GB的RAM并想使用所有可用的RAM,我可以只使用malloc/memset组合键mmap,还是还有我不知道的另一种选择?

我想编写一系列简单的程序,这些程序可以同时运行,并保留进程中使用的所有RAM来强制使用交换,并且频繁交换页面。我已经在下面的程序中尝试过了,但这并不是我想要的。它确实分配了内存(RAM?),并强制使用交换(如果正在运行足够的实例),但是当我sleep不打电话时,这只是锁定了内存的使用(因此,实际上没有交换任何东西)程序?),还是我误会了一些东西。

例如,如果我运行了3次,我是否会在前两个实例中使用2GB(全部)RAM,然后第三个实例将前两个实例之一(从RAM中)和当前实例交换到RAM中?还是仅使用磁盘或虚拟内存运行实例3?

这就提出了另一点,我是否需要分配足够的内存来使用所有可用的虚拟内存以及要使用的交换分区?

最后,mmap这样做是否会更好(或其他任何C函数。地狱,甚至其他语言,如果适用)?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MB(size) ( (size) * 1024 * 1024)
#define GB(size) ( (size) * 1024 * 1024 * 1024)


int main(){
    char *p;
    p = (char *)malloc(MB(512));
    memset(p, 'T', MB(512));
    printf(".5 GB allocated...\n");

    char *q;
    q = (char *)malloc(MB(512));
    memset(q, 'T', MB(512));
    printf("1 GB allocated...\n");
    printf("Sleeping...\n");

    sleep(300);
}

**编辑:我正在为我的OS使用CentOS 6.4(带有3.6.0内核),如果有帮助的话。


问题答案:

这非常依赖于OS /计算机。

在大多数操作系统中,都不分配RAM。它们都分配VM空间。它们使一定范围的进程虚拟内存有效使用。通常,操作系统会在第一次写入时稍后分配RAM。在此之前,这些分配不会使用RAM(除了将它们列为有效VM空间的页表之外)。

如果要分配物理RAM,则必须使每个页面(sysconf(_SC_PAGESIZE)使您的系统页面大小)变脏。

在Linux中,您可以在中查看包含所有详细信息的VM映射/proc/self/smapsRss是该映射的驻留集(RAM中驻留了多少),其他所有脏的东西都将被交换掉。所有非脏内存将可供使用,但在那之前将不存在。

您可以使用以下方法使所有页面变脏

size_t mem_length;
char (*my_memory)[sysconf(_SC_PAGESIZE)] = mmap(
      NULL
    , mem_length
    , PROT_READ | PROT_WRITE
    , MAP_PRIVATE | MAP_ANONYMOUS
    , -1
    , 0
    );

int i;
for (i = 0; i * sizeof(*my_memory) < mem_length; i++) {
    my_memory[i][0] = 1;
}

在某些实现中,也可以通过将MAP_POPULATE标志传递给来实现mmap,但是(取决于您的系统)如果尝试映射更多内容而没有可用的RAM
mmapENOMEM则可能会失败。



 类似资料:
  • 编译以下代码时: 我得到警告提示: 在I之后,程序中断似乎没有改变。 以下是输出: 问题2:进程在启动时是否在堆上分配内存以供将来使用?还是编译器更改了分配的时间点?否则,为什么? 可以设置参数来控制的行为,并且有一个名为的参数,一般情况下: 如果请求的内存小于它,则将使用; 如果请求的内存大于或等于它,则将使用; 该参数的默认值是(在我的系统上),但在我的测试程序中我使用了1MB,所以选择了,当

  • 假设我定义了一个插件,如下所示: 在当地的一个建筑里。Gradle,我写 我希望合并两个buildscript部分,以便在插件中定义存储库,在build.gradle中定义依赖项,但似乎本地声明重写了插件,我最终出现了一个错误,指示“没有定义存储库”。 如果我通过配置注入从顶层构建。Gradle,结果是一样的吗? 也许正确的解决方案是让插件提供一个ext闭包来定义useMyRepos(),类似于m

  • 我有一个图像压缩应用程序,现在有两个不同版本的内存分配系统。在最初的一个例子中,malloc无处不在,在第二个例子中,我实现了一个简单的池分配器,它只分配大块内存,并将部分内存返回给myalloc()调用。 我们注意到,使用malloc时会产生巨大的内存开销:在内存使用量最大的时候,malloc()代码对于1920x1080x16bpp映像需要大约170 MB的内存,而池分配器只分配48 MB,其

  • 问题内容: 该MMAP文件说,下面讲的标志MAP_NORESERVE。 不要为该映射保留交换空间。当保留交换空间时,可以保证可以修改映射。如果没有保留交换空间,则在没有物理内存可用的情况下,可能会在写入时获得SIGSEGV。 我真正想要的只是保留虚拟内存地址,而没有分配实际的物理内存。可以使用MAP_NORESERVE的mmap来完成此操作吗?如果我想使用任何物理内存,我将在MAP_NORESER

  • 问题内容: 在Linux上,如果我愿意,malloc实际上是做什么的? 我确定它会为分配分配一个虚拟地址(通过遍历空闲列表并在必要时创建新的映射),但是它实际上是否创建了1 GiB的交换页?还是当您实际触摸它们时就创建地址范围并创建页面? (我之所以指定Linux,是因为该标准在这些细节上没有任何说明,但是我很想知道其他平台也可以这样做。) 问题答案: Linux确实也推迟了页面分配。“乐观的内存

  • 问题内容: 我从来没有见过这样的声明,它是否存在于Java世界中? 问题答案: Java的版本是-它创建指定类型的新对象。 在Java中,内存是为您管理的,因此您不能显式或对象。