I\'ve been learning these topics and read many articles and books but they all lack some complementary information and confused me even more. So here, I’d like to explain wh
Some people use the term "Virtual memory" as if it were synonymous with the Page File, since the Page File represents the part of your allocated memory that is not "real" memory (i.e. RAM). But most people consider "Virtual Memory" to be the entire abstraction layer that the Operating System gives to programs, which combines the RAM and the Page File.
I'm not sure which of these definitions is favored by Mac OS, though it seems unlikely that your computer would not have any paged memory allocated, so I'm guessing that it probably is adding 8GB of paged memory to your 8GB of actual RAM, for a total of 16GB of available (virtual) memory.
Remember that because the Operating System manages memory allocation and deallocation requests, it is free to do just about whatever it wants. My understanding is that most operating systems have different memory allocation tables for each process, so they could literally give the same virtual memory address to multiple programs, but those memory addresses would map to different actual blocks in memory. So a 64-bit operating system can allocate the maximum amount of 32-bit addresses to multiple 32-bit programs--they're not all limited to the same 32-bit memory addresses.
However, there are limits: the operating system can have limits set to the size that the page file is allowed to grow to. So unless you've deliberately told your Operating System to do so, it will probably not have 64 GB of total Virtual Memory. And even if it did, it can't allocate all 64 GB to every program, so you'd most likely have an OutOfMemory error before the OS allocates a virtual address at 0xFFFFFFFFF to your program. (In fact, I wouldn't be surprised to learn that 0xFFFFFFFFF is actually a reserved error-code location, similar to 0x0.) But since the addresses that your program knows about have no correlation to true memory addresses, there's a possibility that you'd end up being allocated a memory address that your program thinks of as 0xFFFFFFFFF, even if the operating system isn't using anywhere near that much memory.
Is there one big giant page table which includes all the pages for every process or each process has its own page table?
Likely both... and then some.
So, supposing a process has been allocated memory at address 0x00000002, when it goes to load the value out of that memory address, the operating system might recognize that this actually maps to the real memory address 0x00000F23, and that is the memory address whose value will actually be fetched into the CPU register. Or, it could realize that it has moved the page containing that address onto the disk somewhere, in which case the operating system will find an empty part of memory and load the page's data from the disk into that memory first. (Again, this memory address doesn't have any correlation with the original memory address that the program requested.)
If there isn't any empty memory to pull the page from, the OS will first have to move some data out of memory and into the page file. It tries to intelligently determine which memory is least likely to be used in the near future. But sometimes you end up with memory constantly getting requested shortly after it gets swapped to the disk, only to replace the next piece of memory that a program was about to request. This "thrashing" is what causes computers with insufficient memory to go really, really slow, since disk accesses are orders of magnitude slower than memory accesses.