在Windows上,我知道内存实际上会返回到操作系统.
这两种做事方式之间有什么大的区别,还是两种不同的方式做同样的事情?如果这两种方法有任何利弊,那么它们是什么?
编辑:谢谢你的澄清.我一直认为这是一个操作系统的事情(因为在类UNIX系统中,进程似乎永远不会减小,但在Windows中也是如此).
在两者中,有两个级别的分配.操作系统以大块(一页或多页;在x86上,页面大小通常为4096字节)为进程分配内存.在进程中运行的运行时库细分此空间并将其中的一部分分配给您的代码.
要将内存返回到操作系统,首先必须将从这些大块之一分配的所有内存释放到运行时库.然后,运行时库可以(如果需要)告诉操作系统释放该块内存.
在Linux上,你有brk和mmap. brk控制分配给你的进程的大块内存的大小;你可以扩展或缩小它,但只能在一端.当malloc需要更多内存来分配时,它传统上会扩展这块内存,并在可能的情况下缩小它.然而,萎缩并不容易;它在最后需要一个单字节的错误定时分配,以使它无法收缩,即使该分配之前的所有内容都已被释放.这是“Unix不释放内存”的来源.
但是,还有匿名的mmap.匿名mmap从操作系统请求一块内存,该内存可以放在进程内存空间的任何位置.这个块可以在不再需要时轻松返回,即使后来的分配尚未发布. malloc也使用mmap(特别是对于大型分配,其中一大块内存可以在被释放后轻松返回).
当然,在Windows和Linux上,如果你不喜欢运行时库中内存分配器(或分配器)的行为,你可以使用自己的,从操作系统中询问内存并按照你想要的方式细分它(有时候)从另一个分配器询问内存,但是在较大的块中).一个有趣的用途是为与任务相关的所有内存(例如,Web服务器请求)分配一个分配器,在任务结束时完全丢弃该分配器(不需要单独释放所有部分);另一个有趣的用途是用于固定大小对象的分配器(例如,五字节对象),这可以避免内存碎片.