内存映射
当程序运行后,就会有0~4G地址范围(并不能全部访问,地址没有对应物理内存)
如果访问了没有映射过的地址(逻辑地址)就会产生段错误
当首次使用malloc申请内存时,malloc没有内存可分配,它会向操作系统申请进行内存映射,操作系统会直接映射33页(4096(即4*1024)字节)内存交给管理,当再次使用malloc申请内存时,malloc会把已经有的33页内存进行分配
内存管理
malloc分配的每一块内存之间至少相隔4个字节(内存存储的是下一块要分配的内存)
注意:
如果这4个字节的内存被破坏会影响下次的内存分配:
1、如果在内存分配前破坏这4个字节,会影响下块内存的申请
2、如果在内存分配后再破坏这4个字节,会影响这块内存的释放
堆内存越界的后果:
1、破坏malloc的维护信息,可能会造成申请或释放时的错误(如下)
malloc.c:2451: sYSMALLOc: Assertion
free(): invalid pointer: 0x0846xxxx
2、脏数据:没有被malloc分配的内存虽然也可以使用,但当malloc再次把它分配后,之前存储的数据会被破坏(有多个指针指向了同一块内存)
3、段错误:越界范围超过33页
4、一切正常:访问用来对齐的字节
内存碎片
已经被释放但不能被再次使用的内存
由于申请时间和释放时间不匹配,造成已经释放的内存不能继续使用
内存碎片是不可能杜绝的,只能尽可能减少
如何减少内存碎片的产生:
1、尽量使用栈内存
2、尽量申请大块内存
3、不要频繁地申请释放内存
内存泄露
当程序结束后,操作系统所分配给它的资源会被全部回收
为何还会有内存泄露:
1、有些程序是不能轻易停止的(服务器端)
2、由于指针被错误赋值、业务逻辑错误,导致堆内存无法被释放,而需要使用时只能再次申请,长期积累导致可用的内存越来越少 -> 内存泄露
如何避免:
1、谁申请谁释放
2、谁知道该释放谁释放