免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: cc8829
打印 上一主题 下一主题

请教:如何将动态申请的空间及时的还给系统 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2004-04-13 12:17 |只看该作者

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

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

论坛徽章:
0
12 [报告]
发表于 2004-04-13 12:54 |只看该作者

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

哈哈,大伙讨论的很复杂了,不过我想说的是,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.

论坛徽章:
0
13 [报告]
发表于 2004-04-13 13:02 |只看该作者

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

我在freebsd上没有看到楼上的说法。
并且在freebsd好象是会及时归还给系统吧

  1. DEBUGGING MALLOC PROBLEMS
  2.      The major difference between this implementation and other allocation
  3.      implementations is that the free pages are not accessed unless allocated,
  4.      and are aggressively returned to the kernel for reuse.
复制代码


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

论坛徽章:
0
14 [报告]
发表于 2004-04-13 13:11 |只看该作者

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

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

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
15 [报告]
发表于 2004-04-13 13:14 |只看该作者

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

同意楼上!

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

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

论坛徽章:
0
16 [报告]
发表于 2004-04-13 13:26 |只看该作者

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

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

论坛徽章:
0
17 [报告]
发表于 2004-04-13 13:44 |只看该作者

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

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

论坛徽章:
0
18 [报告]
发表于 2004-04-13 14:47 |只看该作者

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

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

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

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

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

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

上面的想法我已经在 RH linux 测试过了。大家可以在自己的系统上测试以下程序。特别希望看到flw在SUN上、wangrujun在freebsd上以及各位朋友在不通系统上的测试情况。

  1. #include <stdio.h>;
  2. #include <malloc.h>;

  3. int main()
  4. {
  5.   char* p;

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

  9.   p = (char*)malloc( 1024 );

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

  12.   free( p );

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

  16.   fprintf( stderr, "free memories allocated by malloc not immediately\n");

  17.   return 0;
  18. }
复制代码


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

以上是我的关于这个问题的一些个人看法,希望能够回答一些朋友提出的问题。正确与否,欢迎大家讨论指正。

论坛徽章:
0
19 [报告]
发表于 2004-04-13 14:51 |只看该作者

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

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

即使free后的空间被重新分配了,依然可以用原指针访问这块区域。但是,这么做的结果不合乎逻辑,会造成这块区域数据的不可靠性,因为新旧两个指针指向的是同一块区域。
从逻辑上说,旧的指针所指向的区域已经释放了,旧指针就没有意义了,不应当再被使用了。如果free的原型是void free( void ** ),则可以由free函数本身将旧指针清空,但这样的函数接口显然不如现在的接口自然合理,因此,空间释放后指针的清空应当属于应用程序的工作。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP