V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
nicolemeimei
V2EX  ›  问与答

有关虚拟内存&物理内存的疑问

  •  
  •   nicolemeimei · 2020-12-01 11:34:30 +08:00 · 1216 次点击
    这是一个创建于 1487 天前的主题,其中的信息可能已经有所发展或是发生改变。
    通常程序会有一个内存分配器,用于管理内存地址,并且是管理虚拟地址。印象中的内存分配器基本都会很有序的按照一定策略分配 /释放内存,但我联想到这些都是虚拟地址,最后还需要靠 OS 映射到物理地址,那管理虚拟地址的必要性在哪里?我理解的 internal fragmentation 和 external fragmentation 都是针对虚拟内存的,但毕竟是虚拟的,最后不是还是得从真实的物理地址拿数据吗,最坏的情况是虚拟地址管理的井井有条,但 OS 映射的物理地址乱七八糟,那访问时间不久会大大的增加了?

    不知道我上面的理解哪里有问题,请多指教,非常感谢🙏
    7 条回复    2020-12-06 13:07:11 +08:00
    dilu
        1
    dilu  
       2020-12-01 12:45:17 +08:00 via Android
    虚拟内存通过 CPU 中的 mmu 进行映射操作,查询页目录跟页表。好处是进程直接内存是隔离的,同时用户空间不会影响到内核空间。你想想实地址模式跑个 qq 就把操作系统搞挂的场景?这样做大大的增加了稳定性。同时还方便进行碎片内存的回收,也简化了上层调用者的调用逻辑。

    你看计算机的各个技术方向,都是分层思想,尽量让每一层都不互相干扰。
    msg7086
        2
    msg7086  
       2020-12-01 13:47:32 +08:00
    「这些都是虚拟地址,最后还需要靠 OS 映射到物理地址,那管理虚拟地址的必要性在哪里?」

    虚拟地址的必要性和最终是否映射到物理地址是无关的,前者无法推出后者结论。
    就像说你到了 100 岁牙全掉光了,那现在为什么还要保护牙齿一样。

    如果像你说的,去掉了虚拟内存地址,那么所有的程序最终都得读写物理地址。那程序是不是还是要有一个机制去管理哪些地址不能读写,哪些地址能读写。那最后不就等于在每个程序内部重新写了一个内存管理器么。

    既然每个程序都要实现内存管理器,不如整个拿出来抽象成一个虚拟内存地址,然后程序只要很简单地申请和释放就行了。
    msg7086
        3
    msg7086  
       2020-12-01 13:49:52 +08:00
    换句话说,没有「必要性」,但是白嫖的开发成本,为什么不拿呢。
    就像说牙齿,反正有假牙,套上也能用,实在不行还能种牙。
    但是你还是会保护牙齿,因为性价比高啊。
    systemcall
        4
    systemcall  
       2020-12-01 15:55:44 +08:00
    虚拟地址与物理地址之间的映射是硬件实现的,优化是硬件厂家的事。SSD 上面系统拿到的照样是虚拟地址,看主控性能
    如果想直接用物理地址,欢迎来到嵌入式。能够直接操作物理内存,不仅仅是可以影响到别的进程那么简单,你甚至可以直接操作硬件
    nicolemeimei
        5
    nicolemeimei  
    OP
       2020-12-03 20:14:12 +08:00
    @msg7086 @dilu 非常感谢你们的回复,我之前的理解和表述确实有问题,管理虚拟地址是有必要的。但我认为虚拟地址与物理地址的映射会影响到程序的性能,但研究内存管理器的相关论文,没有看到这些论文在评估设计的内存管理器时考虑这一点,是我过度解读了吗?
    msg7086
        6
    msg7086  
       2020-12-04 02:15:51 +08:00
    性能当然是有影响的。

    但是你反过来想想,现在的操作系统在管理 CPU 分片的时候也有严重的性能损失。
    你所有的 CPU 时间都是先交给操作系统,然后操作系统从一大堆进程里挑一个,然后把时间片下放给他。
    这个过程每秒钟要执行几十到几百次。

    那么如果是你,你会选择花一个小时写个简单的几十行代码来完成你想做的事情,还是去花个半年时间写一个完整的和 CPU 直接交互的私有时间片管理器,然后绕开操作系统,直接从 BIOS/UEFI 引导进你的小程序,就为了这 5%(猜的)的性能?

    抽象当然会带来性能上的损失,但是他节约下来的,是全球数千亿美元的开发成本。
    一般认为这些都是必须要付出微小代价。
    人力成本只会越来越高,硬件成本只会越来越低,没有必要为了个便宜货去搭上昂贵的人工。
    这也是为什么高级语言才是开发主力,而底层语言终究还是为了基建。
    nicolemeimei
        7
    nicolemeimei  
    OP
       2020-12-06 13:07:11 +08:00
    @msg7086 嗯嗯,我现在明白了这里头的 trade off 。太谢谢您了!感觉思路开阔了很多!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2723 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:03 · PVG 20:03 · LAX 04:03 · JFK 07:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.