If each process has its own address space and it is much larger than the physical memory of the computer, why can’t we just place the stack at the end of this address space and the heap at the beginning, keeping their growth directions towards each other? In this case, we wouldn’t have the situation where the stack collides with the heap, as they are very far apart in the virtual address space. We could simply limit their size so that they cannot request more memory than allowed. This way, there would be no problem with the stack and heap colliding. I’ve been searching for information on this topic... process in virtual memory
For example, ChatGPT suggested the following: "the operating system must store the range of addresses between the heap and the stack in page tables, even if virtual addresses are not used, they still need to be recorded in the table, and physical addresses are assigned as needed. If we placed the stack and heap far apart, it would lead to inefficient memory allocation because the entire range of virtual addresses would need to be reserved in the page table"
I don't understand why? If ChatGPT's explanation makes sense, why do we need to record addresses in the page table that don’t have corresponding physical memory?
I want to understand how the stack and heap are arranged in memory and why it is done this way.
An operating system managing virtual memory using a hardware memory management unit does not have this problem.
The hardware partitions the virtual address pace into pages that are mapped onto the physical address space, where the mapping is completely controlled by software.
This way it is possible to map arbitrary many virtual pages to the existing physical pages, but this is not the whole story.
Very important is that the hardware checks access to the virtual pages. If a process tries to access a virtual page that is not allocated, e.g. during a stack overflow out of its virtual page, the hardware issues a page fault that lets the operating system trap to a handling routine. This routine would then allocate a new physical page to the not allocated virtual page, allocate it, and let the interrupted process continue. The new virtual page that extends continuously the stack in the virtual address space map then to a non-continuous arbitrary physical page.
And if by chance all physical pages are currently used, one of them is paged out to disk to free physical memory for the extended stack.
So, if the operating system is correctly programmed, the stack can never collide with the heap.
The memory management unit is also e.g. responsible for statistics, how often and when a page has been used, which helps to find a page that can be paged out to disk. It also allows to set attributes to a page, e.g. instruction, read-only or read-write.