分类: LINUX
2014-03-06 14:53:09
问题现象:在redhat 64位系统中,用户态进程申请malloc 8M的内存,free后,查看进程的RSS并未减少,释放的内存未还给系统。
而在redhat 32未系统中,释放后的内存会立刻还给系统。
原因:redhat是采用的glibc作为c库,glibc采用ptmalloc作为内存管理机制。malloc有一个mmap门限默认是128k,当第一次分配内存大于128k时,ptmalloc会直接调用mmap申请内存,而不是去堆中分配。那么释放的时候也就直接调用munmap直接释放了。
但是为了提升效率,mmap门限是动态可调的,在第一次分配的内存释放的时候,ptmalloc会判断,这个mmap分配的内存大小如果在可调正范围内,那么会调高mmap的门限值。32位系统mmap门限范围是128k——512k(超过512k一律永远用mmap申请),64位的范围是128k——32M。
64位系统中,malloc一次大约会分配8M内存,测试过程可以清晰的看到,第一次new之后delete立刻是释放了内存的,因为这是用mmap申请的内存,此时mmap的门限也调高到了12M,所以后面再new就从堆中分配内存,再次delete的时候就没有立即释放内存。
而32位系统中,其mmap门限最大为512k,所以每次new都是mmap分配的,所以每次都会直接释放内存。
ptmalloc的堆机制缓存内存是从效率考虑,毕竟mmap要比malloc慢很多。那么什么时候堆会释放内存呢(就是收缩),必须要满足堆收缩的条件(主堆是堆顶部空闲128k,副堆是整个64M堆空间空闲(64位))。
所以测试用例中的现象是正常的,用64位系统会获得相同测试结果。
缓存的内存空间是可以被复用的,它只要不连续增长就没有什么问题。