Board logo

标题: 内存分配问题 [打印本页]

作者: caopengly    时间: 2008-8-12 17:31     标题: 内存分配问题

我们在ALPHA Tru64、SUN Solaris等OS上测试了如下代码:
---------------
#include <unistd.h>;
#include <stdlib.h>;
#include <stdio.h>;

main()
{
char* data;
for (int size = 1; size <= 10; size ++)//line:8
{
printf("the %d-th malloc-free,size:%d0M...\n", size, size);
data = (char *)malloc(size*1024*1024*10);
sleep(10);
free(data);
sleep(10);
}
for (int size = 11; size <= 15; size ++)
{
printf("the %d-th malloc-free,size:%d0M...\n", size, size-10);
data = (char *)malloc((size - 10)*1024*1024*10);
sleep(10);
free(data);
sleep(10);
}//line:23
while(1) // line:24
{
printf("sleep 10s...\n");
sleep(10);
}
return 0;
}
---------------
测试中,在当size=1(line:8)时,进程所使用的实际内存和虚存分别为232K和12.2M。
当进程运行到line 23之后,while(1)语句时,进程所使用的实际内存和虚存分别为232K和102M。
依我们的理解,在line 23之后,进程陷入死循环时,应该释放所使用的实际内存和虚存,即应该
恢复到size=1前,进程开始时的状态。
这一点谁知道是什么原因?

------所使用获取内存使用情况的shell文件
#!/bin/ksh

while :
do
ps -ef -o rssize -o vsize -o pcpu -o pmem -o comm | grep test_malloc;

date

echo ==========================================
sleep 5

done
内存分配问题请教

这是正常的. 因为内存的管理是由系统库来完成 or libc malloc allocator. 当用户程控申请一块内存, libc malloc 先看有没有以前FREE的内存能满足要求. 如不行, 再向KERNEL申请一块不小于用户要求的内存.这时候虚存增加.
而当用户FREE一块内存, libc malloc 可以把这块内存放在FREE LIST上, 为以后用. 所以你看不到虚存减少. 当然libc malloc 也可以把这块内存还给KERNEL. 只有这时虚存减少.
你可以用mallinfo()看到libc malloc 的状态. 也可以用mallopt()改变libc malloc 的参数.

内存分配问题请教

实际上, 加上下面几行CODE(直接向KERNEL申请内存), 你就能看到预期的效果.
// malloc sz bytes from kernel
sbrk(sz);
// return sz bytes to kernel
sbrk(-sz);

内存分配问题请教

你对我提的问题“内存分配问题请教”回复到:
“当然libc malloc 也可以把这块内存还给KERNEL. 只有这时虚存减少.
你可以用mallinfo()看到libc malloc 的状态. 也可以用mallopt()改变libc malloc 的参数.
”。
那么你所说的“当然libc malloc 也可以把这块内存还给KERNEL. 只有这时虚存减少. ”该如何做?如何用代码实现?
另外,函数sbrk()和malloc()有何不同?
谢谢!!!

内存分配问题请教

我们系统中有很多进程使用malloc()和free(),能否有什么办法不需要改动程序代码而只是配置操作系统OS的参数,达到真正释放虚存的目的?
谢谢!!!

内存分配问题请教

用户程序不能改变CRT MALLOC的行为. 除非你自己写ALLOCATOR. 当你的程序调用malloc()的时候, CRT MALLOC再调用更底层的sbrk(). 这就是它们的不同.
其实进程的虚存没释放是没关系的, 你为什么担心呢?

内存分配问题请教

在我们的系统(Tru64)中有一个进程rt_server,在开始运行时其使用的实际内存和虚拟内存分别是8.1M和28.9M,该进程运行10天后使用的实际内存和虚拟内存分别是103M和140M(事实上没有内存泄漏)。Tru64上对每个进程有一个参数:per_proc_data_size,即每个进程可以使用的data size,我们设定的该参数大小为128M。不知这个参数是指的实际内存的大小还是虚拟内存的大小,我们会发现rt_server在某些时候malloc()失败。这才是我们要解决的问题。请指点问题所在。
进程使用的实际内存和虚拟内存到底有什么关系?谢谢。

内存分配问题请教

ps还能这样用呐
楼主解释一下那个ps命令吧

内存分配问题请教

1.你概念上理解的不对,OS可以释放VM和PM,你的PROCESS只能释放PM,PROCESS的VM是单向增长的(你可以TRACK你MALLOC的返回值观察).
2.你的问题不是什么PROCESS VM释放的问题,是DATA SIZE需要调整的问题.

内存分配问题请教

>;2.你的问题不是什么PROCESS VM释放的问题,是DATA SIZE需要调整的问题.
如何调整DATA SIZE啊?

内存分配问题请教

data size应当是虚拟内存的大小, UNIX都有.请看ulimit command(Solaris, Linux, AIX, HPUX, not sure about Tru64). 如果机器资源够, 我们一般设成unlimited.(只对server)
>; ulimit -d unlimited

你的进程是个server, 跑了几天后,会有fragmentation. 所以实际内存和虚拟内存都不是起始值.我们的server常要每星期reboot一次.

虚拟内存是你向KERNEL reserve 的空间(CRT allocator call sbrk() when you call malloc()), 实际内存是程序读写虚拟地址时, KERNEL为你分配的RAM (page_on_demand). ALLOCATOR有两重方法得到虚拟内存:sbrk & mmap. sbrk得到的内存很难再反回OS, 因为只用HEAP最上层的FREE的地址才能sbrk(-size)反回OS. 这是柳五随风说的"PROCESS的VM是单向增长的". 这一般是很对的. 另一方面mmap得到的内存, FREE的时候, 可以munmap完全反回OS. 在LINUX上, 当malloc的SIZE>;128K时, 就是这种情况.

要减少实际内存和虚拟内存消耗, 需要一个好的MEMORY ALLOCATOR. server本身也要合理运用内存. 这就一句话说不清了.


作者: caopengly    时间: 2008-8-12 17:37

这是对allocator对内存分配中的疑问的讨论,觉得比较有意思,和大家分享一下。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0