静态/栈/堆内存使用的不一致性及相关技术疑问
静态/栈/堆内存使用的不一致性及相关技术疑问
嘿,我来帮你把这两个内存相关的疑问捋明白:
问题1:堆中释放的内存会对其他进程可用吗?
这个得分情况讨论,不能一概而论:
- 如果你用的是系统标准库(比如glibc)里的
malloc/free,调用free释放内存时,不一定会立刻把内存还给操作系统。标准库会维护一个自己的内存池,把释放的内存先存起来,等当前进程后续再调用malloc时,直接从内存池里取——这样比每次都跟OS申请/释放效率高得多。但如果内存池里的空闲块实在太大,或者进程本身内存占用压力变小,标准库会主动把部分内存归还给OS,这时候这部分内存就可以被其他进程使用了。 - 但如果是你自己写的简单自定义
malloc实现,比如直接用brk/sbrk申请了一块固定大小的堆空间,然后自己在这块空间里做内存分配管理,那除非你主动调用brk把堆的大小缩小、把不用的空间还给OS,否则这整块内存都会一直属于你的进程,其他进程是用不了的。
所以“堆的限制是RAM总量”是从操作系统全局角度来说的,但具体到单个进程的内存管理,还要看内存分配器的实现逻辑。
问题2:C中的float变量编译成汇编的.long,是不是属于静态分配、全程占用内存?
这得看你这个float变量的类型:
- 如果是全局变量或者用
static修饰的局部变量,那它确实会被放到静态存储区(.data段,如果是可修改的;或者.rodata段,如果是常量)。汇编里的.long就是把这个float的IEEE754二进制值直接存在静态存储区里,这块内存从程序启动到退出都会一直被占用,属于静态分配没错。 - 但如果是普通局部变量(没有static修饰),正常情况下编译器会把它分配在栈上——汇编里应该是通过栈指针偏移来访问,不会出现
.long放在静态段的情况。不过如果这个局部变量是个常量(比如你写了float x = 3.14;,而且后续没修改它),编译器可能会做优化,把它放到静态存储区里,这时候就会出现你看到的.long情况,但这是优化后的结果,不是默认行为。
总结一下:只有全局/static的float才是默认静态分配、全程占用内存,普通局部float默认在栈上,只有在作用域内才会占用内存。
备注:内容来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

