内存分配和进程内存使用
Memory allocation and process memory use
我想了解为什么动态分配的多次调用的数据使用的内存比直接在代码上指定或通过 malloc
.
的单次调用分配的内存多
例子
例如,我在C:
中做了以下两段代码
test1.c: int x 分配给 malloc
int main (void)
{
int *x;
int i, n=1048576; //n=1024*1024;
printf("size = %lu\n", n* sizeof(int));
for(i=0; i<n; i++)
{
x = malloc(sizeof(int));
*x=i;
}
printf("Look at top and then press something to finish.");fflush(stdout);
getc(stdin);
return 0;
}
为了简单起见,我在这里没有使用 free。
当程序等待交互时,我在另一个终端查看顶部函数,它显示如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1384 root 20 0 41300 34076 1300 S 0.0 3.3 0:00.47 test1
test2.c: int x 不是动态分配的
int main (void)
{
int x[1048576]; //x[1024*1024]
int i, n=1048576;
printf("size = %lu\n", n* sizeof(int));
for(i=0; i<n; i++)
{
x[i]=i;
}
printf("Look at top and then press something to finish.");fflush(stdout);
getc(stdin);
return 0;
}
顶部显示:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1352 root 20 0 12404 5500 1304 S 0.0 0.5 0:00.05 test2
我也做了第三个代码,结果和test2一样,我用的是:
x = malloc(n*sizeof(int));
for(i=0; i<n; i++)
{
x[i]=i;
}
为什么进程的内存使用差异如此之大?那是因为malloc申请了新的内存页,有内存被浪费了吗?或者 malloc
分配更多内存?
test1 使用总内存的 3.3%,test2 使用 0.5%.
环境:
我正在 docker.
中的 Centos 5 64 位上执行这些测试
虚拟环境内存:
$ free -m
total used free shared buff/cache available
Mem: 995 98 845 3 51 808
Swap: 1162 194 967
每次用户请求一些内存时,系统都需要做一些内务处理。当仅使用您的指针调用 free 足以让系统取消分配其内存时,应该记住这一点。
因此,在您的第一个示例中,您请求内存 n
次,而在第二个示例中仅请求一次。您打算使用的内存是相同的,但系统必须 "remember" 的信息不同。
必须跟踪每个内存分配,以便 free()
可以释放 space 以供重用。实际上,这意味着分配了最小内存大小;对于 32 位程序,它可以是 8 或 16 字节,对于 64 位程序,它可以是 16-32 字节(这取决于系统和使用的 C 库的版本)。
当您分别分配一百万个整数时,每个整数都使用 8-32 个字节,因此您实际上使用了 8-32 MiB 的内存。当您在堆栈上的单个数组中分配一百万个整数时,您使用了 4 MiB 的内存。
因此您会发现进程大小存在显着差异。
当然,第一个程序几乎泄漏了所有内存,但这与您要问的问题无关。
我想了解为什么动态分配的多次调用的数据使用的内存比直接在代码上指定或通过 malloc
.
例子
例如,我在C:
中做了以下两段代码test1.c: int x 分配给 malloc
int main (void)
{
int *x;
int i, n=1048576; //n=1024*1024;
printf("size = %lu\n", n* sizeof(int));
for(i=0; i<n; i++)
{
x = malloc(sizeof(int));
*x=i;
}
printf("Look at top and then press something to finish.");fflush(stdout);
getc(stdin);
return 0;
}
为了简单起见,我在这里没有使用 free。 当程序等待交互时,我在另一个终端查看顶部函数,它显示如下:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1384 root 20 0 41300 34076 1300 S 0.0 3.3 0:00.47 test1
test2.c: int x 不是动态分配的
int main (void)
{
int x[1048576]; //x[1024*1024]
int i, n=1048576;
printf("size = %lu\n", n* sizeof(int));
for(i=0; i<n; i++)
{
x[i]=i;
}
printf("Look at top and then press something to finish.");fflush(stdout);
getc(stdin);
return 0;
}
顶部显示:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1352 root 20 0 12404 5500 1304 S 0.0 0.5 0:00.05 test2
我也做了第三个代码,结果和test2一样,我用的是:
x = malloc(n*sizeof(int));
for(i=0; i<n; i++)
{
x[i]=i;
}
为什么进程的内存使用差异如此之大?那是因为malloc申请了新的内存页,有内存被浪费了吗?或者 malloc
分配更多内存?
test1 使用总内存的 3.3%,test2 使用 0.5%.
环境:
我正在 docker.
中的 Centos 5 64 位上执行这些测试虚拟环境内存:
$ free -m
total used free shared buff/cache available
Mem: 995 98 845 3 51 808
Swap: 1162 194 967
每次用户请求一些内存时,系统都需要做一些内务处理。当仅使用您的指针调用 free 足以让系统取消分配其内存时,应该记住这一点。
因此,在您的第一个示例中,您请求内存 n
次,而在第二个示例中仅请求一次。您打算使用的内存是相同的,但系统必须 "remember" 的信息不同。
必须跟踪每个内存分配,以便 free()
可以释放 space 以供重用。实际上,这意味着分配了最小内存大小;对于 32 位程序,它可以是 8 或 16 字节,对于 64 位程序,它可以是 16-32 字节(这取决于系统和使用的 C 库的版本)。
当您分别分配一百万个整数时,每个整数都使用 8-32 个字节,因此您实际上使用了 8-32 MiB 的内存。当您在堆栈上的单个数组中分配一百万个整数时,您使用了 4 MiB 的内存。
因此您会发现进程大小存在显着差异。
当然,第一个程序几乎泄漏了所有内存,但这与您要问的问题无关。