It's not completely clear from your question or the image, but with the 'System Address Space' you probably mean the area between 2GB-4GB. This indeed takes up half of the theoretical 4GB space, but there is a valid reason for it.
Normally with 32-bits you can address 4 GB of memory (2^32=4294967296) so it would seem logical to have 4 GB of address space, not 2 GB. The reason for this is the following:
Suppose you have 2 pointers, like this in C/C++:
char *ptr1;
char *ptr2;
I now want to know what the difference is between the two pointers, like this:
offset = ptr2 - ptr1;
What should be the data type of 'offset'?
If we don't know whether ptr1 comes before ptr2 or vice versa, the offset can be positive or negative. Now if both ptr1 or ptr2 are between the range 0 - 2GB, then the offset is always between -2147483648 and +2147483647, which fits exactly in a 4 byte signed integer.
However, if ptr1 and ptr2 would be able to access the full 4 GB address space, offset would be between -4294967296 and +4294967295 which doesn't fit in a 4 byte signed integer anymore.
If you are sure that you are never doing this kind of calculations in your application, or you are sure that if you subtract 2 pointers that they will be never more apart than 2 GB (or your vectors are always smaller than 2 GB), you can tell the linker (Windows, Visual Studio) that your application is LARGEADDRESSAWARE. This linker flag sets a bit in the executable, and if a 32-bit Windows is booted correctly (on XP you had to boot with the /3GB) flag, Windows gave you 3GB instead of 2GB (only for the LARGEADDRESSAWARE executables).
The remaining 1GB is still used for operating system data structures (but I have no details about them).
If you are running a 64-bit Windows, then things get even more interesting, because LARGEADDRESSAWARE executables will then get 4GB of memory. Apparently, the operating system data structures are now stored somewhere in the 64-bit address space, outside the 4GB used by the application.
Hope this clarifies a bit.