Quantcast
Viewing all articles
Browse latest Browse all 3

Answer by Margaret Bloom for Challenges about the amount and characteristics of code within an executable file loaded into memory per each process

The processor divides the address space into sets of addresses called pages.
On x86 a typical page is of size 4KiB but other sizes are possible (e.g. 1GiB, 2 MiB).
Pages are continuous, so the first page is from address 0x00000000 to address 0x00000fff, for each address there is a unique page associated with it.

A page has a set of attributes, the whole point of paging is to associate a set of attributes to each address.
Since doing it for every single address would be too prohibitive, pages are used instead.
All the addresses in a page share the same attribute.

I somewhat simplified the story by not differentiating between virtual addresses (the ones that actually are paginated, i.e. they can have attributes) and physical addresses (the real addresses to use, a virtual address can be mapped to a different physical address).

Among the various attributes there are:

  • One that tells the CPU if the page is to be considered not loaded.
    Basically, this makes the CPU generate an exception when an instruction tries to access the page (e.g. read from it, including execution, or writing to it).
  • Permissions
    Like read-only, non-executable, supervisor, etc.
  • The physical address
    The main use of paging is isolation, it can be accomplished by letting the same virtual address X be mapped into different physical addresses Y1 and Y1 for the process P1 and P2 respectively.

Remember that these attributes are per-page, they apply to the whole range of addresses in a page (e.g. they affects 4 KiB addresses for a 4 KiB page).

With this in mind:

  1. When a process is created all its pages are marked as non-present. Accessing them would make the CPU fault.
    When the OS loads the program, a minimal set of pages are loaded (e.g. the kernel, part of it, the common libs, part of the program code and data) and marked present.
    When the program accesses a page not loaded the OS checks if the address was allocated by the program, if so (this is a valid page fault) it loads the page and resumes execution.
    If the address was not allocated, an invalid page fault occurs and the exception reported to the program itself.

  2. I don't know the exact number of pages loaded, one could verify it in different ways, including taking a look at the Linux kernel (for the Linux case).
    I'm not doing it because the actual strategy used may be complex and I don't find it particularly relevant: the OS could load the whole program if it is small enough and the stress on the memory is low.
    There could be settings to tweak to chose one or another strategy.
    In general, it is reasonable to assume that only a fixed number of pages is loaded optimistically.

  3. Factors that influence the decision could be: the amount of memory available, the priority of the process loaded, policy on the system made by the sysadmin (to prevent bloating it), type of the process (a service like a DBMS could be marked as memory intensive), restriction of the program (e.g. in a NUMA machine a process may be marked to use, prevalently, local memory, thereby having access to less memory than the total available), euristics implemented by the OS (e.g. it know that the last execution required K pages of code/data within M milliseconds from the start).
    To put it simply, and short, the algorithm used to load the optimal number of pages has to predict the future a bit, so the usual considerations of the case are made (i.e. assumptions, simplifications, data collection and similar).


Viewing all articles
Browse latest Browse all 3

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>