• 关于Linux平台malloc的写时拷贝(延迟分配)【转】


    Linux内核定义了“零页面”(内容全为0的一个物理页,且物理地址固定),应用层的内存分配请求,如栈扩展、堆分配、静态分配等,分配线性地址后,就将页表项条目指向“零页面”(指定初始值的情况除外),这样“零页面”就被所有进程共享,当向页面执行写入操作时,内核就会新分配一个物理页,实行“写时拷贝”操作,这样就实现了物理页面的延迟分配(如果只有读没有写,则无需另分配物理页)。

    动态内存通过glibc库的malloc函数分配,当现有地址空间不够时(即malloc维护的空闲链表中没有足够空间),就调用brk/sbrk扩展进程空间的相关线性区段,然后将对应页表项条目指向“零页面”,写操作时再分配新页面。这样,只要进程空间足够大,malloc操作总是成功的——即使申请的内存大于系统物理内存——失败会发生在为“写时拷贝”分配新页面的时候,当系统可分配内存不足时,且有进程要求分配新页面,内核会Kill该进程,并打印类似“Out of Memory: Killed process xx (xxx).”的信息。这就是Linux的“OOM Killer”特性。

           因此不能通过检测malloc的指针是否为NULL,来判定系统能否支持申请的内存大小(即空闲内存大于申请内存)。

     malloc操作示意图

    malloc操作示意图

    malloc分配的这种机制,给应用层判断动态内存是否可分配增加了难度。因为内存不足的错误被延迟到写入操作的时候,而在这里内核没有提供相关接口给应用层(只是发送SEGV信号给临死的进程)。

  • 相关阅读:
    软件编程思想读后感
    上交所历史数据分析系统项目总结
    2013学习总结----JavaScript
    快来领取你专属的css背景图案
    小朋友,听说你还不会css中的条纹背景?
    特殊要求下的背景定位的解决方案
    css中多边框实现的方式
    一个按钮样式测试出你的 css功力
    一次优雅的表单验证设计
    使用JavaScript浅谈组合模式
  • 原文地址:https://www.cnblogs.com/freedesert/p/3330517.html
Copyright © 2020-2023  润新知