代码之家  ›  专栏  ›  技术社区  ›  Aditya Sehgal

释放总是(可移植地)为进程释放和保留内存还是返回到操作系统?

  •  6
  • Aditya Sehgal  · 技术社区  · 14 年前

    我已经阅读了free()“generally”不会将内存返回到操作系统。我们能方便地利用这个吗 特征 的()例如,这是便携式的吗?

     /* Assume I know i would need memory equivalent to 10000 integers at max
        during the lifetime of the process */
    
     unsigned int* p = malloc(sizeof(unsigned int) * 10000);
    
     if ( p == NULL)
      return 1;
    
     free(p);
    
     /* Different points in the program */
    
     unsigned int* q = malloc(sizeof(unsigned int) * 5);
    
     /* No need to check for the return value of malloc */
    

    我正在写一个演示,我可以提前知道有多少个 call contexts 支持。

    可以分配吗 "n" "call contexts" structures 提前,然后 free 他们马上就来。那能保证我的未来吗 malloc 呼叫不会失败?

    这对我的效率有什么好处吗?我在想,如果一个大的块是最初获得的,现在是免费的,那么“if”check plus会更好地管理内存。这会导致碎片减少吗?

    10 回复  |  直到 14 年前
        1
  •  7
  •   Amardeep AC9MF    14 年前

    您最好先保留分配的初始内存块,然后使用池将其提供给应用程序中的客户机。依靠深奥的行为来维护代码的稳定性是不好的形式。如果 任何东西 改变,你可能会处理坏的指针和程序崩溃。

        2
  •  5
  •   dmckee --- ex-moderator kitten    14 年前

    你要的是 便携式的 以及控制 内存接口的操作系统端 .

    任何 操作系统(因为C是最广泛移植的语言之一)。

    想一想,请记住,OSS的结构和目标各不相同,其需求和属性也各不相同。

    通常的C API只定义了从接口的C端看事物应该如何表现,而不是在操作系统端应该如何表现,这是有原因的。

        3
  •  4
  •   Carl Norum    14 年前
    1. 不,你不能可靠地做这种事。它是 便携式的 只有在它是有效的C并且可能 编译 无论你在哪里尝试,但是依赖这种假定的(和未记录的)行为仍然是不正确的。

    2. 你也不会得到任何明显更好的表现。一张简单的支票 NULL 从回报 malloc() 不是什么让你的程序变慢了。如果你认为你所有的电话 马尔洛() free() 放慢你的程序速度,用你想要的行为写下你自己的分配系统。

        4
  •  4
  •   JesperE    14 年前

    你不能 可移植地 依赖于 malloc() . 你只能依靠 马尔洛() 给你一个指向给定大小的块内存的指针,直到你调用 free() .

        5
  •  4
  •   Nikolai Fetissov    14 年前

    嗯,不。 malloc(3) 内部是否调用 brk(2) 如果数据段对于给定的分配请求太小,则扩展它。它确实触及了一些内部簿记的页面,但一般情况下,并非所有分配的页面都会在这一点上由物理内存支持。

    这是因为许多操作系统 内存过量使用 -承诺无论应用程序请求什么,不管可用的物理内存是多少,希望不是所有的内存都将被应用程序使用,其他应用程序释放内存/终止,并作为最后的手段放弃交换。在Linux上说 MalOC(3) 几乎从不失败。

    当内存被实际引用时,内核必须找到可用的物理页来备份它,创建/更新页表和TLB等——对页错误的正常处理。所以,同样的,不,除非你去触摸分配的块中的每个页面,否则你以后不会得到任何加速。

    披露者:上述内容对于Windows可能不准确(因此,不,再次-没有任何接近便携式的东西)。

        6
  •  3
  •   nos    14 年前

    不,没有保证释放()不会释放内存,也没有保证第二个malloc会成功。

    即使是“一般”不将内存返回到操作系统的平台,有时也会这样做(如果可以的话)。你可能会以你的第一个malloc成功而告终,而你的下一个malloc却没有成功,因为同时系统的其他部分耗尽了你的内存。

        7
  •  3
  •   Puppy    14 年前

    一点也不。它根本不便携。此外,不能保证另一个进程不会使用问题中的内存—C运行在许多设备上,如嵌入式设备,其中虚拟内存寻址不存在。它也不会减少碎片化——你必须知道机器的页面大小并分配精确的页面数量——然后,当你释放它们时,它们就会再次被取消碎片化。

    如果您真的想保证内存不正确,可以使用malloc来创建一个大的块,并手动将对象放入其中。这是唯一的办法。至于效率,你必须在一个极度匮乏的设备上运行,以节省一些IFS。

        8
  •  3
  •   adobriyan    14 年前

    malloc(3)也做mmap(2),因此,free(3)做munmap(2),因此,第二个malloc()理论上会失败。

        9
  •  1
  •   Jerry Coffin    14 年前

    C标准可以理解为需要这一点,但从实践的角度来看,有一些已知的实现并不遵循这一点,因此无论是否需要,您都不能真正依赖它。

    因此,如果您希望保证这一点,那么您将非常需要编写自己的分配器。一个典型的策略是从malloc(或其他)中分配一个大的块,并为程序的其余部分分配子块,以便从该大块(或可能是多个大块)中使用。

        10
  •  0
  •   INS    14 年前

    为了更好地控制,您应该创建自己的内存分配器。内存分配器的一个例子是 this one . 这是获得可预测结果的唯一方法。其他依赖模糊/未记录的功能和工作的一切都可以归因于运气。