c - 分配 ram 显示任务管理器中 ram 使用量的两倍

标签 c windows-7 malloc

做一些分析(内存和速度) 我一直被 win7 似乎分配的 RAM 正好是我要求的两倍这一事实所困扰...注意这是我第一次在 win7 上进行这样的主动分析,所以我真的不知道会发生什么。

我在 win7(64 位)下使用 MSVC 快速版循环分配精确数量的 RAM。该应用程序以 32 位编译和运行。

我分配了 24 MB 的内存,任务管理器显示我的应用程序使用了 48MB(在所有内存列下,包括已提交,因为我实际上是在新区域中进行内存复制)。当我再得到 24 个(现在应该是 48MB)时,我的应用跳转到 96,等等。

这些被分配为 1,000,000 个 24 字节结构。

我在网上搜索过,但没有找到与我的观察结果完全相符的东西。

有人知道吗?

如果这只是操作系统的诡计(或无能?),是否有任何工具可以提供进程的实际内存消耗? (很难找到漏洞,当应用程序开始涌现时 ;-)

[------------ 已编辑,附加信息------------]

注意(通过控制台标题栏中的路径)我正在 Release模式下构建(使用 MSVC 2010 的所有默认“空”项目设置),因此没有分配额外的“调试”内存(可以是在某些项目上相当广泛)。

这是一个简短、完整的 C 应用程序,它说明了行为:

#include <stdio.h>
#include <assert.h>
#include <conio.h>
#include <stdlib.h>
typedef unsigned int u32;
typedef struct myStruct MYS;
struct myStruct {
    u32 type;
    union {
        u32 value; 
        char * str;
        void * data;
        MYS ** block;
        MYS * plug;
    };
    u32 state, msg,  count, index;
};
int main(int argc, char *argv[]){
    int i, j;
    MYS *ref;
    printf ("size of myStruct: %d\n\n", sizeof(MYS));
    for(i=0; i < 10; i ++){
        printf("allocating started...\n");
        for (j = 0; j < 1000000 ; j ++){
            ref = (MYS *) malloc(sizeof(MYS));
            assert(ref);
            memset(ref, 0, sizeof(MYS));
        }
        printf("   Done... Press 'enter' for Next Batch\n");
        _getch();
    }
    _getch();
    return 0;
}

和一张图片,显示了一个循环后我的机器上的内存。每隔一次运行,它会增加 ~48MB 而不是 24MB!

process info after 1 loop (should be ~24MB)

最佳答案

这可能是由于填充、内部管理结构和内存对齐限制的组合。

当您调用 malloc(size) 时,您实际上并没有获得 size 字节的缓冲区。您得到一个至少 大小 字节的缓冲区。这是因为,出于效率原因,您的操作系统更喜欢只提供几种不同大小的内存缓冲区,而不会调整缓冲区以节省空间。例如,如果您在 Mac OS 上请求 24 字节,您将获得 32 字节的缓冲区(浪费 25%)。

将您的操作系统用于管理 malloc 缓冲区的结构(可能占每次分配的几个额外字节)添加到该分配开销,以及填充可能会增加对象大小的事实(到你的编译器首选对齐的倍数),你会发现将数百万个小对象分配到单独的缓冲区中是非常昂贵的。

长话短说:只分配一个 sizeof (YourType) * 1000000 的大缓冲区,您应该看不到任何明显的开销。分配一百万个 sizeof (YourType) 对象,您最终会浪费大量空间。

关于c - 分配 ram 显示任务管理器中 ram 使用量的两倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6655185/

相关文章:

c++ - glReadPixels 不更新值

c++ - 更好的折叠循环索引计算

java - 在 Windows 7 上的 Eclipse Luna Release (4.4.0) 中克隆 GitHub 存储库

batch-file - 批处理文件 : If directory exists, 做某事

c - 如何在 C 中正确使用 strtok 以防止内存泄漏?

c - C 中的字符串动态分配

c - C switch 语句中的随机标签不会导致错误

c - 在 ncurses 上重绘

android - 创建 android 模拟器时出现 16 位 ms-dos 子系统错误

C malloc,重新分配。如何从数组中删除单个元素。