C free()不释放嵌入式linux中的内存。

C free()不释放嵌入式linux中的内存。,c,free,embedded-linux,C,Free,Embedded Linux,我在嵌入式Linux中使用malloc()分配了内存(大约10 MB)。并检查了可用内存,它是67080 kB,但即使使用free()释放它,它仍然保持不变。只有在应用程序终止后,内存才再次可用。free()不会使释放的内存对系统可用,如果是,如何使其可用。free是一个libc库调用。它将堆空间标记为可重用。它不保证关联的虚拟映射将被释放。只有在操作系统释放脏虚拟映射后,该内存才会再次在系统范围内可用。这只能在页面块中发生 另外,如果您使用malloc和family分配了内存,但没有使用它,那

我在嵌入式Linux中使用malloc()分配了内存(大约10 MB)。并检查了可用内存,它是67080 kB,但即使使用free()释放它,它仍然保持不变。只有在应用程序终止后,内存才再次可用。free()不会使释放的内存对系统可用,如果是,如何使其可用。

free
是一个libc库调用。它将堆空间标记为可重用。它不保证关联的虚拟映射将被释放。只有在操作系统释放脏虚拟映射后,该内存才会再次在系统范围内可用。这只能在页面块中发生

另外,如果您使用
malloc
和family分配了内存,但没有使用它,那么在此之前它实际上不会消耗物理内存,因此释放它不会起任何作用

free()不会使释放的内存对系统可用

不,通常不会。 malloc()通常通过低级调用
sbrk()
mmap()
从操作系统请求内存。一旦分配给应用程序,free()只会将内存返回到属于该应用程序的内存池中。也就是说,它不会返回到操作系统以便在另一个进程中使用。(尽管在某些情况下有一些启发式方法可以做到这一点)

如果交换空间到位,问题就不那么严重了,操作系统将交换应用程序未使用的内存,以便为所需的额外物理内存腾出空间

如果是,如何提供

退出应用程序

或者您需要编写自己的内存分配器来实现这一点(在一般情况下,这不是一项容易的任务,尤其是如果您不想牺牲开销和速度的话)


对于一块相对较大的10MB内存,您只需使用
mmap()
请求匿名内存,当您
munmap()
该内存块时,该内存将被释放回操作系统。

摘自malloc 3手册页:

通常,malloc()从堆中分配内存,并调整 使用sbrk(2)根据需要确定堆的大小。分配块时 对于大于MMAP_阈值字节的内存,glibc malloc() 实现将内存分配为私有匿名映射 使用mmap(2)。默认情况下,MMAP_阈值为128 kB,但为 可使用mallopt调节(3)

您可以尝试修改MMAP_阈值,以便通过使用malloc调用MMAP。如果这样做,free将保证通过mmap分配的内存在释放后会立即返回到系统。

您的malloc()调用从系统获取内存,并维护一个堆数据结构,用于跟踪进程中已使用和可用的内存。free()调用将内存返回到堆中,在堆中它们被标记为空闲,但它们仍然是进程内存的一部分


如果希望内存释放将页面返回到系统,则必须编写自己的内存管理器,但请记住,它只能在正确的条件下完全释放内存:这取决于应用程序的行为,取决于您的分配和释放是否跨越页面边界并干净地反碎片,等等。您需要了解应用程序的内存分配行为,以了解这是否会有任何好处。

这取决于malloc实现,但通常会有一个内部池,因此,释放指针可能不会立即产生任何效果。可能的重复:当您
释放
内存时,系统仍会为您保留它,以防您需要再次分配它(因此它不必重做内存映射表)。系统将在需要时获取内存。请注意,如果您正在运行一种(逐渐减少的通用)uClinux或没有MMU嵌入式Linux配置,则将内存返回到系统将变得更加困难。@克里斯:是的,我正在使用嵌入式Linux(类似于uClinux的自定义版本)。谢谢。我需要另一个信息。是否有任何方法可以使系统从应用程序中获得释放的内存?@Satchit只有系统调用才能做到这一点。为此,您需要使用
mmap/munmap
手动管理内存分配。另外,
madvise/MAP\u DONTNEED
可以在有效的映射上执行此操作。请注意,这些系统调用仅适用于系统页面块中的分配。检查系统页面大小的
sysconf(SC|u PAGESIZE)
;retval=munmap(mem,40960);我的页面大小是4096字节。但仍然没有自由。我应该用不同的方式使用mmap吗?@Satchit你真的在内存中分页了吗?如果您
mmap
内存,但不使用它,那么它也不会消耗任何RAM。在每一页上写点东西,把它们弄脏。或者将
MAP\u POPULATE
传递到
mmap
,但这在不同的操作系统上有不同的行为。我使用了内存,只是用一些值初始化它。实际上,我正在使用cat/proc/meminfo来查看可用空间。我使用它的方式如下:int*mem=(int*)mmap(NULL,40960,PROT_READ,PROT_WRITE,MAP_ANONYMOUS,MAP_SHARED,-1,0);retval=munmap(mem,40960);仍然无法释放到系统。。请提出建议。@Satchit在这里当然有效,尽管不需要地图共享,但请使用地图私有。您将很难确定是否已将40kb返回到操作系统,但只需几次库调用,您的进程可能突然映射了更多内存(例如写入标准输出),并且总体内存统计数据将波动超过40kb。你如何确定它不起作用?试试你提到的10Mb。请确保检查munmap()是否成功。即使我使用了40 KB的内存,它仍然无法释放到系统中。虽然不是必需的