我正在编写独立于操作系统的无锁队列,到目前为止它工作得很好,但内存管理存在小问题。我不确定它的gcc问题还是我的问题。问题:当元素添加到列表时,内存增加,但是当从列表中删除元素时(free(elementPointer);)内存使用不会改变。
但是当我使用pthreads时,N个生产者和M个消费者(1<N<20, 1<M<20)
的内存使用量总是大约10mb(当试图添加和删除~10kk元素时),所以看起来像免费工作。
有趣的是,在VS 2010中(相同的代码,没有线程)免费工作正常,内存被释放(观看任务管理器)。
我做了测试,添加了1kk元素,添加完所有后,逐个删除所有元素(没有线程)。
Linux - 0.08秒
Windows~57秒
Linux(不含免费) - 0.07秒
Windows(不含免费) - 0.9秒
所以,问题是,为什么在没有使用线程的情况下Linux C中没有释放内存? 如有必要,我可以发布代码。
GCC版本:4.4.3
答案 0 :(得分:10)
在许多操作系统上,free()
不会再次为操作系统提供内存,而是“仅”用于malloc()
的新呼叫。这就是为什么你没有看到外部内存使用量下降的原因,但是当你通过线程增加新的分配数量时,内存会被重新使用,所以总的使用量不会通过屋顶。
答案 1 :(得分:8)
Malloc不必将内存返回给操作系统。类Unix系统上的大多数malloc实现都没有这样做。特别是对于较小的物体尺寸。
这是出于性能原因。
我刚才注意到这可能不清楚。 “malloc”是指与malloc函数相关的整个子系统 - malloc,free,realloc,calloc以及libc可能实现的任何特殊函数。
答案 2 :(得分:5)
为了简化过程,有两个内存管理器在动态内存分配中工作:操作系统内存管理器,以及进程内存管理器(可能超过之一)。 OS内存管理器为各个进程内存管理器分配“大块”内存。每个进程内存管理器都会跟踪分配的段以及“自由段”。进程内存管理器不会将自由段返回到操作系统内存管理器,因为它可以更有效地保留它,以防以后需要分配更多内存。