一个关于内存分配的帖子

 
请教:如何将动态申请的空间及时的还给系统

我发现malloc出来的空间free之后并没有马上还给系统,而是必须在进程结束之后才还给系统,不知有没有别的更好的办法,既可以动态的申请空间,又可以随时的将空间还给系统

请教:如何将动态申请的空间及时的还给系统

那你就实现自己的内存管理策略。

请教:如何将动态申请的空间及时的还给系统

>;>; 我发现malloc出来的空间free之后并没有马上还给系统,而是必须在进程结束之后才还给系统
虽然不是那么绝对,但一般的编译器好像都是这么实现的。有没有编译选项可以改变这一行为,还没有看到有资料介绍这一点。

>;>; 不知有没有别的更好的办法,既可以动态的申请空间,又可以随时的将空间还给系统
你可以试试用 mallopt 函数调整动态内存分配的参数,即在程序开始加上如下一句:
[code]  mallopt( M_MMAP_THRESHOLD, 0 )[/code]
这时,malloc函数其实是调用 mmap 来实现内存分配的,保证了释放时能够及时归还系统。需要包含头文件 malloc.h。注意这个函数不是 ANSI C标准中规定的,有些系统中可能没有,或者即使有这个函数,但是可能没有定义它的实现。如果用 GNU C 库的话不妨试试。

请教:如何将动态申请的空间及时的还给系统

对了,楼上的朋友,我还想问一句,mmap是建立内存与磁盘文件映射关系的,如果我要用它实现malloc的功能,是不是说我得将内存映射到/dev/null上呢?另外是不是还存在内存共享的问题呢,即其他进程操作这个文件可能会改变我内存的数据呢(我这部分内存可能并不想共享)?
谢谢执教哦 :roll:

请教:如何将动态申请的空间及时的还给系统

我记得,free的内存系统并不会立即回收,只会简单的标记一下,你用top之类的命令察看的时候可以看的出来。因为这样可以加快下次程序malloc的速度。

请教:如何将动态申请的空间及时的还给系统

>;>; 我还想问一句,mmap是建立内存与磁盘文件映射关系的,如果我要用它实现malloc的功能,是不是说我得将内存映射到/dev/null上呢?
/dev/zero

>;>; 另外是不是还存在内存共享的问题呢,即其他进程操作这个文件可能会改变我内存的数据呢(我这部分内存可能并不想共享)?
那就 mmap 时指定 flags 为  MAP_PRIVATE,而不是 MAP_SHARED。

还有,上面你测试的结果如何?达到你的要求了吗?

请教:如何将动态申请的空间及时的还给系统

有点别的事情,还没来得及测试,试了之后我马上把结果贴出来。

请教:如何将动态申请的空间及时的还给系统

我提供一点我的看法.
首先,malloc提供的占用地址可能是已经分配的区地址,它包含了除malloc返回空间其他的一些数据,因此当free时系统不会直接free,而是等待本区释放时才释放,这与unix的内存管理有关.如果希望将自己分配的动态空间中不包含其他数据,建议使用brk和sbrk函数自己分配区,并维护它.

请教:如何将动态申请的空间及时的还给系统

malloc申请的内存free之后没有还给系统,而是必须在进程结束之后才还给系统???

如果是这样的话,我们还free它干吗?干脆就等进程结束系统自动收回不就得了。free岂不是多此一举?

请教:如何将动态申请的空间及时的还给系统

绝对同意lcd的观点.free后,其实内存就已经是在系统的控制之下了.已经不是我们的进程独占的了.而是受系统的内存管理程序控制了.所以,也没必要区别是否打标记之类的.只要你free了,系统就不会因为你的进程没退出而产生内存泄漏.
如果不free的话,系统内存很容易就耗光了.这个我做过测试了.

请教:如何将动态申请的空间及时的还给系统

楼上的说明很清楚,但是不是说,free()以后的数据块都是在进程退出后真正释放,而不是本区不使用就释放?还有在free()后的数据空间如果已经反给了操作系统,但我发现我的一个指向本空间的指针仍然可以对本区域操作,是否会存在下面情况,如果有一块空间被free了(误操作),程序仍然使用空间,同时本程序分配新的空间个其他操作时,系统将本空间分配给了其他操作,则两个操作存在竞争,还是先前的操作在系统重新分配本空间后不能再对本空间进行操作了????
请知道的朋友解释一下,谢谢!

请教:如何将动态申请的空间及时的还给系统

哈哈,大伙讨论的很复杂了,不过我想说的是,malloc本身不是系统调用,而是系统调用brk上的wrapper,之所以free没有把内存归还给操作系统,就是为了加快下次malloc的速度,因为下次malloc不必非得调用brk系统调用,而是直接从内存池里拿出来一块就好了。
并且按照man手册,free确实不会把空间归还给系统,而是只有当程序结束了才会归还
     The argument to free() is a pointer to  a  block  previously
     allocated  by malloc(), calloc(), or realloc(). After free()
     is executed, this space is made available for further  allo-
     cation  by  the application, though not returned to the sys-
     tem. Memory is returned to the system only upon   termination of  the  application.

请教:如何将动态申请的空间及时的还给系统

我在freebsd上没有看到楼上的说法。
并且在freebsd好象是会及时归还给系统吧
[code]
DEBUGGING MALLOC PROBLEMS
     The major difference between this implementation and other allocation
     implementations is that the free pages are not accessed unless allocated,
     and are aggressively returned to the kernel for reuse.
[/code]

我想这个东西跟具体操作系统有关

请教:如何将动态申请的空间及时的还给系统

同意楼上的观点。这个的确和操作系统对于内存管理的实现而不同。
在linux下面,free的空间不会立即返回给系统。

请教:如何将动态申请的空间及时的还给系统

同意楼上!

我查了 C99 对 free 的描述,没有找到相关字样。
而且,在 SCO 中的描述确实也与 zhxlanjuan 贴出来的不同,
在 SUN 上则相同。

我想也应该是操作系统的实现有关。

请教:如何将动态申请的空间及时的还给系统

[b]个人看法[/b]
free不会立即取消物理内存的映射,这是因为:每一个malloc操作并不一定都是申请整块物理内存的,如果上次申请时剩下的部分够大,malloc就不必再申请映射新的物理内存。这就是说,malloc返回的地址是随机的,不是一定以物理映射单位的整数倍的形式存在。这样,当free时,就不可能简单地取消物理内存的映射。

请教:如何将动态申请的空间及时的还给系统

同意楼上的看法,但我也提到free与不free是否向楼上老兄说的那样,系统可分配与否的情况呢,我实验做一个连表,free后发现原指针仍然可以调用数据,是否是由于系统未将空间再次分配出去呢???

请教:如何将动态申请的空间及时的还给系统

程序(进程)只能访问属于自己的内存数据空间。这个数据空间可以是静态分配的(如定义变量),也可以是动态分配的(如用 malloc 函数等)。静态分配的空间由操作系统直接管理,负责分配和释放;动态分配的空间是人们向操作系统申请,经操作系统同意而划归给本进程使用的内存空间。只要进程没有向操作系统提出“释放”(free)这块空间的请求,操作系统就会保证这块内存空间是本进程专有的。

一个进程完全可以只申请内存空间(malloc),而不释放(free)空间。但是请想一下,如果进程不断地 malloc(比如在一个循环过程中),系统的内存资源很快就会用光的。所以,用过的内存空间如果不再需要了,立即释放是一个好习惯。

对其它系统如 Windows 等不是太清楚,但是 linux 在进程结束的时候会回收动态分配的内存,包括哪些没有被进程释放的内存。所以,如果只是在 linux 上写一些简单的测试程序的话,即使 malloc 之后没有 free,你也不要担心这部分内存得不到回收。在程序结束的时候,系统会自动回收它们的。

如果进程向操作系统提出释放这块内存的请求,对于这个请求,不同的系统的反应是不一样的:有的系统可能会立即释放;有的系统(如 linux 等)不会释放,仍然把这块内存空间作为进程专有空间(即此时系统不会把这块内存空间分配给其它进程使用),但是却标定为“已释放”,进程在下一次向操作系统申请空间的时候,系统会优先考虑这块“已释放”的空间,这样做的目的是加快内存分配的速度;对于释放内存的请求,是不是还有系统考虑其它的响应方式,我就不清楚了。

在C语言中,动态分配的内存只能通过指针来访问。前面已经提到过,程序只能访问属于自己的内存数据空间。如果一个指针访问到了不属于自己的内存空间,程序会在输出 Segmentation fault 之后异常终止。根据这一点,我们可以判断内存空间在 free 之后,系统到底是否真正地回收了这块空间:如果是真正地释放了,再次访问这块空间会产生Segmentation fault的错误,程序会异常终止;如果不是真正释放,而是到了程序结束时才真正释放,由于这块内存还属于程序专有,只要程序没有结束,应该就还能正常访问这块内存,就象没有释放过一样,程序正常结束。

上面的想法我已经在 RH linux 测试过了。大家可以在自己的系统上测试以下程序。特别希望看到flw在SUN上、wangrujun在freebsd上以及各位朋友在不通系统上的测试情况。
[code]
#include <stdio.h>;
#include <malloc.h>;

int main()
{
  char* p;

  // enable this will change the memory mallocation method (in Linux),
  // and perhaps it will change the free behave.
  //  mallopt( M_MMAP_THRESHOLD, 0 );

  p = (char*)malloc( 1024 );

  *p = 'a'; // no problem
  fprintf(stderr, "before free = %c/n", *p);

  free( p );

  // access error or not, depending on your operating system
  *p = 'b';
  fprintf( stderr, "after free = %c/n", *p );

  fprintf( stderr, "free memories allocated by malloc not immediately/n");

  return 0;
}
[/code]

大家也可以把 mallopt( M_MMAP_THRESHOLD, 0 ); 前面的注释去掉,试试 mallopt 函数是否也在你的系统上起作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值