«¿Cuáles son los límites de memoria para aplicaciones de 32 bits en un Windows de 64 bits?»
Puedes acceder a toda la memoria del sistema desde tu aplicación. Aunque sea mucho más de 4 gigas.
La cuestión no es que no puedas tener más memoria, sino que no puedes mapearla toda en el espacio de direcciones virtual de la aplicación. La cosa se complica un poco: tendrás que usar controladores de memoria, y mapear dinámicamente las regiones de memoria con las que estás trabajando y desmapear las regiones que no se necesitan realmente para liberar algo de espacio de direcciones. Esto no equivale a liberar y asignar la memoria: conservará su contenido y estará disponible para tu aplicación incluso cuando esté sin mapear. Mapear y desmapear es una operación relativamente barata, sólo hay que actualizar las tablas de traducción de direcciones.
Esta era una práctica común para el software de base de datos que tenía que manejar más de 4 gigas en las antiguas máquinas de 32 bits. También era crucial para los controladores de hardware que tenían que manejar grandes búferes DMA, como varios cientos de megabytes. El espacio total de memoria del kernel es de 1 o 2 gigas en diferentes versiones de Windows de 32 bits, y puede estar muy fragmentado. Te cuento lo que ocurre si intentas asignar 500 megabytes con AllocateContiguousMemorySpecifyCache() en XP de 32 bits: el sistema se cuelga durante media hora, intentando frenéticamente reorganizar el espacio de direcciones del kernel para atender tu petición, y suele fallar incluso si tienes 4 gigz en la máquina. Solíamos asignar el buffer DMA en listas de descriptores de memoria (MDL), y mapear dinámicamente sólo las regiones de las que queríamos leer o escribir. Funcionaba como un encanto, a la velocidad del rayo. Pude obtener casi toda la memoria del sistema (alrededor de 3 gigas) a pesar de que el espacio total de direcciones del kernel era de sólo 1 giga!
Manejar más de 4 gigas no es en absoluto un problema para Windows de 32 bits. Las versiones domésticas estaban limitadas, pero haz una búsqueda de las versiones de servidor. ¡No puedo recordar el límite teórico para la MMU de dos niveles en todos los procesadores x86 después del 386, creo que es de 2 terabytes! Hasta este límite, el soporte de software es relativamente sencillo.
La vida es más fácil con el espacio de direcciones lineal de 64 bits, pero no porque puedas tener más memoria. Realmente no se puede, simplemente es más fácil de hacer. Pero también se hacía de forma rutinaria mucho antes de la llegada de los sistemas de 64 bits.
Diría que la mayor ventaja es que la fragmentación del espacio de direcciones virtual ya no es un problema. Cuando los ordenadores tenían megabytes de memoria, la fragmentación de la memoria física podía evitarse mapeando la pequeña memoria física en un espacio de direcciones virtual mucho mayor. Independientemente de lo fragmentada que estuviera la memoria física, el espacio de direcciones virtual de 32 bits podía suavizarse. De hecho, esta no era una solución real, sino que nos limitamos a dar una patada a la lata en el camino. Cuando empezamos a tener gigabytes de memoria física, volvió el problema de la fragmentación. Obviamente, tener un espacio de direcciones que inicialmente era cientos o miles de veces mayor que la memoria física, no era suficiente. Con la transición 32 bits -> 64 bits, ahora tenemos un espacio de direcciones que es 4.000 millones de veces mayor. Eso «debería ser suficiente para cualquiera» – al menos durante algunos años.