How is RAM allocated? [closed]

依然范特西╮ 提交于 2019-12-06 02:51:25

问题


This is a noob question about computer science: How is ram allocated?

Fo example, I use Windows. Can I know which adresses are used by a program? How does Windows allocate memory? Contiguous or non contiguous? Is it the same thing on Linux OSes ?

And, can I have access to the whole ram with a program? (I don't believe in that, but...)

Do you know any good lectures/documentation on this?


回答1:


First, when you think you are allocating RAM, you really are not. This is confusing, I know, but it's really not complicated once you understand how it works. Keep reading.

RAM is allocated by the operating systems in units called "pages". Usually, this means contiguous regions of 4kiB, but other sizes are possible (to complicate things further, there exists support for "large pages" (usually on the order of 1-4MiB) on modern processors, and the operating system may have an allocation granularity different from the page size, for example Windows has a page size of 4kiB with a granularity of 64kiB).
Let's ignore those additional details and just think of "pages" that have one particular size (4KiB).

If you allocate and use areas that are greater than the system's page size, you will usually not have contiguous memory, but you will nevertheless see it as contiguous, since your program can only "think" in virtual addresses. In reality you may be using two (or more) pages that are not contiguous at all, but they appear to be. These virtual addresses are transparently translated to the actual addresses by the MMU.
Further, not all memory that you believe to have allocated necessarily exists in RAM at all times, and the same virtual address may correspond to entirely different pieces of RAM at different times (for example when a page is swapped out and is later swapped in again -- your program will see it at the same address, but in reality it is most likely in a different piece of RAM).

Virtual memory is a very powerful instrument. While one address in your program can only refer to [at most] one physical address (in a particular page) in RAM, one physical page of RAM can be mapped to several different addresses in your program, and even in several independent programs.
It is for example possible to create "circular" memory regions, and code from shared libraries is often loaded into one memory location, but used by many programs at the same time (and it will have different addresses in those different programs). Or, you can share memory between programs with that technique so when one program writes to some address, the value in the other program's memory location changes (because it is the exact same memory!).

On a high level, you ask your standard library for memory (e.g. malloc), and the standard library manages a pool of regions that it has reserved in a more or less unspecified way (there are many different allocator implementations, they all have in common that you can ask them for memory, and they give back an address -- this is where you think that you are allocating RAM when you are not).
When the allocator needs more memory, it asks the operating system to reserve another block. Under Linux, this might be sbrk and mmap, under Windows, this would for example be VirtualAlloc.

Generally, there are 3 things you can do with memory, and it generally works the same under Linux and Windows (and every other modern OS), although the API functions used are different, and there are a few more minor differences.

You can reserve it, this does more or less nothing, apart from logically dividing up your address space (only your process cares about that).
Next, you can commit it, this again doesn't do much, but it somewhat influences other processes. The system has a total limit of how much memory it can commit for all processes (physical RAM plus page file size), and it keeps track of that. Which means that memory you commit counts against the same limit that another process could commit. Otherwise, again, not much happens.
Last, you can access memory. This, finally, has a noticeable effect. Upon first accessing a page, a fault occurs (because the page does not exist at all!), and the operating system either fetches some data from a file (if the page belongs to a mapping) or it clears some page (possibly after first saving it to disk). The OS then adjusts the structures in the virtual memory system so you see this physical page of RAM at the address you accessed.

From your point of view, none of that is visible. It just works as if by magic.

It is possible to inspect processes for what areas in their address space are used, and it is possible (but kind of meaningless) to translate this to physical addresses. Note that the same program run at different times might store e.g. one particular variable at a different address. Under Windows, you can for example use the VMMap tool to inspect process memory allocation.

You can only use all RAM if you write your own operating system, since there is always a little memory which the OS reserves that user processes cannot use.
Otherwise you can in principle use [almost] all memory. However, whether or not you can directly use that much depends on whether your process is 32 or 64 bits. Computers nowadays typically have more RAM than you can address with 32 bits, so either you need to use address windowing extensions or your process must be 64 bits. Also, even given an amount of RAM that is in principle addressable using 32 bits, some address space factors (e.g. fragentation, kernel reserve) may prevent you from directly using all memory.




回答2:


This is an important question.

RAM is allocated as programs want to. Some languages, such as C or C++, will let you do this yourself. Others, such as Java, will provide you with lovely abstractions for allocating memory.

We allocate memory because we want to store something. RAM is the literal place where variables, etc. are stored as electric binary signals.

Yes, it is quite possible to know which addresses are used by a program. I believe that there are certain tools that do this. If you are writing C++, you can create a pointer to an address on the free store (a large bank of memory): int * i = new int;. If you want to know where this is stored, you just have to std::cout << "int i is at " << i << "." << endl;.

I don't know what contiguous and non-contiguous (sorry 'bout being lazy), but a quick search suggests that Windows is contig and GNU/Linux isn't. Most Windows memory, at the base of all of the abstractions, is on the free store and contains objects or data structures.

Yes, you can access (I believe) the whole RAM with a program. This sounds very bad, but all you have to do is change the pointer address yourself, for example, i ++; (actually a rather common operation for traversing arrays).

I haven't reviewed these, but these videos seem rather credible:

  • C++ Basic Skills: Lesson 14 "Dynamic Memory Allocation" (part 1 of 2)

  • Dynamic memory allocation in C - malloc calloc realloc free

  • More YouTube videos about Java memory allocation



来源:https://stackoverflow.com/questions/21801485/how-is-ram-allocated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!