Jas*_*ker 7 language-agnostic unix windows memory-management
我的理解是,在unix中,当释放内存时,内存不会返回到操作系统,它会继续在下一次调用malloc时再次使用.
在Windows上,我知道内存实际上会返回到操作系统.
这两种做事方式之间有什么大的区别,还是两种不同的方式做同样的事情?如果这两种方法有任何利弊,那么它们是什么?
编辑: 谢谢你的澄清.我一直认为这是一个操作系统的东西(因为在类UNIX系统中,进程似乎永远不会减小,但在Windows中也是如此).
Ces*_*arB 14
Windows和Unix之间没有太大区别.
在两者中,有两个级别的分配.操作系统以大块(一页或多页;在x86上,页面大小通常为4096字节)为进程分配内存.在进程中运行的运行时库细分此空间并将其中的一部分分配给您的代码.
要将内存返回到操作系统,首先必须将从这些大块之一分配的所有内存释放到运行时库.然后,运行时库可以(如果需要)告诉操作系统释放该块内存.
在Linux上,你有brk和mmap.brk控制分配给您的进程的大块内存的大小; 你可以扩展或缩小它,但只能在一端.malloc传统上,当需要更多内存来分配时,会扩展这块内存,并在可能的情况下缩小内存.然而,萎缩并不容易; 它在最后需要一个单字节的错误定时分配,以使它无法收缩,即使该分配之前的所有内容都已被释放.这是"Unix不释放内存"的来源.
但是,也有匿名mmap.匿名mmap从操作系统请求一块内存,该内存可以放在进程内存空间的任何位置.这个块可以在不再需要时轻松返回,即使后来的分配尚未发布.malloc也使用mmap(特别是对于大型分配,其中一大块内存在被释放后可以很容易地返回).
当然,在Windows和Linux上,如果你不喜欢运行时库中内存分配器(或分配器)的行为,你可以使用自己的,从操作系统中查询内存并按照你想要的方式细分它(有时候)从另一个分配器询问内存,但是在较大的块中).一个有趣的用途是为与任务相关的所有内存(例如,Web服务器请求)分配一个分配器,在任务结束时完全丢弃该分配器(不需要单独释放所有部分); 另一个有趣的用途是用于固定大小对象的分配器(例如,五字节对象),这可以避免内存碎片.
请注意,我对Windows的了解比以下更多...
在任何情况下,内存分配和释放实际发生的情况都不是您所描述的.这是因为这里有两个截然不同的概念:计算机拥有的物理内存,程序的虚拟地址空间,程序认为可以使用的内存.
当您的程序从操作系统请求更多内存时,实际发生的是程序中可以访问程序中以前不可用的虚拟地址空间.现代操作系统不能通过只有一个"真实"(即物理)内存池来工作,当它们发出分配请求时它会分配给进程:它为每个正在运行的程序维护虚拟地址空间,并且当程序实际上访问该虚拟地址空间的一部分,确保将其映射到某个物理内存,可能是通过将另一个程序的地址空间的某些部分交换到磁盘上的交换文件.
作为一个例子,在Windows上,每个线程都以(默认情况下)为其分配的兆字节堆栈空间开始.这并不意味着每个线程占用机器的物理内存的兆字节数:只是设置了地址空间以便可以使用它.从这个意义上说,考虑操作系统给你的程序存储器然后程序给它回来它并没有真正起作用 - 它只是不能那样工作.
| 归档时间: |
|
| 查看次数: |
5287 次 |
| 最近记录: |