程序从哪里分配内存? [英] From where does the program allocate memory?

查看:123
本文介绍了程序从哪里分配内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个C和C ++程序员,我使用 malloc new 来分配内存。我只是想知道:操作系统如何分配内存?


  1. 它是从RAM还是从硬盘或从某处分配其他?



div class =h2_lin>解决方案

这实际上比你想象的要复杂得多。操作系统认为页面中的所有内容,它将RAM分成页,将硬盘分成页。当程序启动时,它检查可执行文件需要多少内存,为其选择一些RAM页面,并将这些页面分配给程序。如果RAM中没有可用页面,它需要更老的RAM中的一些页面,并将它们保存到硬盘驱动器的某个地方,然后给这些页面给你。



在程序中分配内存时,程序的内存管理器将尝试在操作系统分配给它的页面中找到一个空闲位置。如果还不够,它会要求操作系统提供更多的页面,而操作系统会提供更多的空间,并为您的应用程序提供更多的页面。



如果您的程序有一段时间没有使用的页面(有时甚至是代码),操作系统可能会将该页面保存到硬盘驱动器,当您的程序尝试再次使用该页面时,操作系统暂停您的程序,将页面重新加载到RAM中,然后恢复您的程序。



这是一个没有意义的图表。

 驱动
+ ------------ + + ------------ + + ------------ +
| 0x00010000 | \ - > | 0x00010000 | | 0x00010000 |
+ ------------ + X + ------------ + + ------------ +
| 0x00020000 | / - > | 0x00020000 | | 0x00020000 |
+ ------------ + + ------------ + + ------------ +
| 0x00030000 | - > ;? / -----> | 0x00030000 |
+ ------------ + / + ------------ +
| 0x00040000 | ----------- / | 0x00040000 |
+ ------------ +
|等|

在这段代码中,你的代码有堆栈内存0x00010000-0x0002FFFF,动态内存,在0x0004000。当你知道!实际上,当你访问0x0002000,操作系统说哦,我已经把你的那个页面存储在RAM地址0x00010000,并为你读取这些值。你没有碰到0x00040000的页面,所以操作系统将它保存到硬盘驱动器的硬盘驱动器位置0x00030000,但如果你尝试使用它会把它带入RAM。操作系统还没有给你地址0x00030000,所以如果你尝试使用它,操作系统会告诉你,该地址没有任何实际的页面,你会得到一个分段故障(segfault)。使这个有趣的是当你要求一个大的连续的块像一个向量,操作系统可以给你任何旧页面,它发现围绕,它不必担心,如果他们是连续的或不。



这也允许操作系统将一个程序的内存从另一个程序中隐藏,这使得他们无法读取或修改其他程序的内存空间。他们是安全的!除了...有方法可以告诉操作系统在两个程序之间共享一个页面(尽管它们在每个程序中可能有不同的地址),允许他们共享页面。 DLLs这样做。



在现实中,它比这更复杂。


As a C and C++ programmer I have used malloc and new to allocate memory. I am just wondering: how does the OS allocate memory?

  1. Does it allocate from RAM or from hard-disk or from somewhere else?

  2. Can I borrow memory form hard disk just in case?

解决方案

It's actually much more complicated than you'd think. The OS thinks of everything in "pages", it splits the RAM into pages, and the hard drive into pages. When your program starts, it checks how much memory your executable takes, chooses some RAM pages for it, and assigns those pages to your program. If there's no "usable" pages in RAM, it takes older some pages in RAM, and saves them to the hard drive somewhere tucked away, and then gives those pages to you.

When you allocate memory in your program, the memory manager of your program will try to find a free spot in the pages the operating system has assigned to it. If there's not enough, it asks the operating system for more pages, and the operating system makes more room and gives your application more pages.

If your program has a page that it hasn't used in a while, (even code sometimes), the operating system may save that page to the hard drive, and when your program tries to use that page again, the operating system pauses your program, reloads the page into RAM, and then resumes your program.

Here's a diagram that makes no sense

C++ addresses           RAM         hard drive
+------------+    +------------+  +------------+  
| 0x00010000 |\ ->| 0x00010000 |  | 0x00010000 | 
+------------+ X  +------------+  +------------+
| 0x00020000 |/ ->| 0x00020000 |  | 0x00020000 |
+------------+    +------------+  +------------+
| 0x00030000 |-->?         /----->| 0x00030000 |
+------------+            /       +------------+
| 0x00040000 |-----------/        | 0x00040000 |
+------------+
|    etc     |

So in this code, your code has stack memory of 0x00010000-0x0002FFFF, and you've allocated some dynamic memory, and that's in 0x0004000. AS FAR AS YOU KNOW! In reality, when you access 0x0002000, the operating system says "oh, I've stored that page of yours in the RAM address 0x00010000" and reads those values for you. You haven't touched the page of 0x00040000 in a while, so the operating system saved it to the harddrive at harddrive location 0x00030000, but will bring it into RAM if you try to use it. The operating system hasn't given you the address 0x00030000 yet, so if you try to use it, the operating system will tell you that address doesn't have any actual pages, and you get a segmentation fault (segfault). What makes this interesting is when you ask for a large contiguous chunk like a vector, the operating system can give you any old pages it finds laying around, it doesn't have to worry if they're contiguous or not. They look contiguous to your program, which is all that matters.

This also allows the operating system to hide memory of one program from another, which keeps them from being able to read or modify other program's memory space. They're safe! Except... there are ways to tell the operating system to share a page between two programs (though they may have different addresses in each program), allowing them to share pages. DLLs do this.

In reality, it's far more complicated than this.

这篇关于程序从哪里分配内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆