Esta pregunta surge de los siguientes fenómenos observados regularmente para los que me gustaría encontrar una explicación:
- El compromiso actual suele ser mayor que el uso físico + el tamaño del archivo de paginación. ¿Que pasa con eso? ¿No debería ser eso imposible? [Parece que esto podría deberse a la compresión. Lo que transforma la pregunta en: ¿Por qué el límite de compromiso no aumenta o algo así? Es decir, ¿cuál es el punto de la compresión si no ayuda con el uso de la memoria?]
- A veces, esto alcanza niveles extremos en los que el compromiso actual supone más del doble del uso de memoria física.
- Cuando la carga de confirmación se llena y Windows comienza a pedirme que cierre cosas, la mayor parte del tiempo la memoria física está alrededor del 60%. Esto parece terriblemente ineficiente.
Esto es en Windows 10, según lo informado por Process Explorer.
La última pregunta que me gustaría responder es: ¿Puedo renunciar a inflar artificialmente mi archivo de página a niveles que mi SSD sin espacio no está preparado para manejar, solo para poder utilizar efectivamente mi memoria física? (O incluso si no estuviera tan completo. Es decir, me gustaría evitar sugerencias como "Haz X/Y/Z en el archivo de tu página".)
Respuesta1
En realidad, esto es bastante sencillo una vez que comprende que el cargo por compromiso representa solopotencial- pero "disponibilidad garantizada si lo desea" - uso de memoria virtual, mientras que el "conjunto de trabajo privado" - que es esencialmente la RAM utilizada por la memoria "comprometida" - esactualutilizar, al igual que el espacio del archivo de paginación. (Pero esto no es todo el uso de RAM, porque hay otras cosas que usan RAM).
Supongamos que estamos hablando de sistemas de 32 bits, por lo que el espacio máximo de direcciones virtuales disponible para cada proceso es normalmente de 2 GiB. (No hay ninguna diferencia sustancial encualquierde los siguientes para sistemas de 64 bits, excepto que las direcciones y tamaños pueden ser mayores, mucho mayores).
Ahora supongamos que un programa que se ejecuta en un proceso utiliza VirtualAlloc (una API de Win32) para "confirmar" 2 MiB de memoria virtual. Como era de esperar, esto se mostrará como 2 MiB adicionales de cargo de confirmación y hay 2 MiB menos de espacio de direcciones virtuales disponibles en el proceso para futuras asignaciones.
¡Pero en realidad todavía no utilizará ninguna memoria física (RAM)!
La llamada VirtualAlloc devolverá a la persona que llama la dirección inicial de la región asignada; la región estará en algún lugar entre 0x10000 y 0x7FFEFFFF, es decir, aproximadamente 2 GiB. (Los primeros y últimos 64 KB, o 0x10000 en hexadecimal, de vas en cada proceso nunca se asignan).
Pero, de nuevo, no existe un uso físico real de 2 MiB dealmacenamiento¡todavía! Ni en la RAM, ni siquiera en el archivo de paginación. (Existe una pequeña estructura llamada "Descriptor de dirección virtual" que describe el va inicial y la longitud de la región privada comprometida).
¡Ahí lo tienes! La carga de confirmación ha aumentado, pero el uso de la memoria física no.
Esto es fácil de demostrar con la herramienta sysinternals testlimit
.
Algún tiempo después, digamos que el programa almacena algo (es decir, una operación de escritura en memoria) en esa región (no importa dónde). Todavía no hay ninguna memoria física debajo de ninguna región, por lo que dicho acceso generará unfallo de página. En respuesta a lo cual el administrador de memoria del sistema operativo, específicamente la rutina de manejo de fallas de página (el "buscapersonas" para abreviar... se llama MmAccessFault), hará lo siguiente:
- asignar una página física previamente "disponible"
- configurar la entrada de la tabla de páginas para la página virtual a la que se accedió para asociar el número de página virtual con el número de página física recién asignado
- añadir la página física al proceso privadoconjunto de trabajo
- y descartar el error de página, lo que provoca que se vuelva a intentar la instrucción que generó el error.
Ahora ha "fallado" una página (4 KiB) en el proceso. Y el uso de la memoria física aumentará en consecuencia y la RAM "disponible" disminuirá. El cargo de confirmación no cambia.
Algún tiempo después, si no se ha hecho referencia a esa página durante un tiempo y la demanda de RAM es alta, podría suceder lo siguiente:
- el sistema operativo elimina la página del conjunto de trabajo del proceso.
- debido a que se escribió desde que se incorporó al conjunto de trabajo, se coloca en la lista de páginas modificadas (de lo contrario, iría a la lista de páginas en espera). La entrada de la tabla de páginas todavía refleja el número de página física de la página de RAM, pero ahora tiene su bit "válido" limpio, por lo que la próxima vez que se haga referencia a ella se producirá un error de página.
- Cuando la lista de páginas modificadas alcanza un umbral pequeño, seescritor de página modificadaEl hilo en el proceso "Sistema" se activa y guarda el contenido de las páginas modificadas en el archivo de paginación (suponiendo que tenga uno), y...
- saca esas páginas de la lista modificada y las coloca en la lista de espera. Ahora se consideran parte de la RAM "disponible"; pero por ahora aún conservan sus contenidos originales de cuando estaban en sus respectivos procesos. Nuevamente, el cargo de confirmación no cambia, pero el uso de RAM y el conjunto de trabajo privado del proceso disminuirán.
- Las páginas de la lista de espera ahora se puedenreutilizado, es decir, usado para otra cosa, como resolver fallas de página de cualquier proceso en el sistema, o usado por SuperFetch. Sin embargo...
- Si un proceso que perdió una página en la lista modificada o en espera intenta acceder a ella nuevamente antes de que la página física haya sido reutilizada (es decir, todavía tiene su contenido original), la falla de la página se resuelve sin leer desde el disco. La página simplemente se vuelve a colocar en el conjunto de trabajo del proceso y la entrada de la tabla de páginas se vuelve "válida". Este es un ejemplo de un error de página "suave" o "barato". Decimos que las listas en espera y modificadas forman un caché de páginas en todo el sistema que probablemente se volverán a necesitar pronto.
Si no tiene un archivo de paginación, los pasos del 3 al 5 se cambian a:
Las páginas se encuentran en la lista modificada, ya que no hay ningún lugar para escribir su contenido.
Las páginas se encuentran en la lista modificada, ya que no hay ningún lugar para escribir su contenido.
Las páginas se encuentran en la lista modificada, ya que no hay ningún lugar para escribir su contenido.
El paso 6 sigue siendo el mismo, ya que las páginas de la lista modificada pueden volver a incluirse en el proceso que las perdió como un error de página "suave". Pero si eso no sucede, las páginas permanecen en la lista modificada hasta que el proceso desasigne la memoria virtual correspondiente (tal vez porque el proceso finaliza).
Hay otros usos del espacio de direcciones virtuales y de la RAM, además de la memoria privada comprometida. Haymapeadoespacio de direcciones virtuales, para el cual el almacén de respaldo es algún archivo específico en lugar del archivo de paginación. Las páginas de vas mapeadas que se paginan se reflejan en el uso de RAM, pero la memoria mapeada no contribuye a la carga de confirmación porque el archivo mapeado proporciona el almacén de respaldo: cualquier parte de la región mapeada que no esté en RAM simplemente se mantiene en el archivo mapeado. Otra diferencia es que la mayoría de las asignaciones de archivos se pueden compartir entre procesos; una página compartida que ya está en la memoria para un proceso se puede agregar a otro proceso sin tener que volver a buscarla en el disco (otro error de página suave).
Y ahí estáno paginablevas, para el cual no existe un almacén de respaldo porque siempre reside en la RAM. Esto contribuye tanto al uso de RAM informado como al "cargo de confirmación".
Parece que esto podría deberse a la compresión. Lo que transforma la pregunta en: ¿Por qué el límite de compromiso no aumenta o algo así? Es decir, ¿cuál es el punto de la compresión si no ayuda con el uso de la memoria?
No. No tiene nada que ver con la compresión. La compresión de la memoria en Windows se realiza como un paso intermedio, en páginas que de otro modo se escribirían en el archivo de paginación. En efecto permite a lalista de páginas modificadasusar menos RAM para contener más cosas, con cierto costo en tiempo de CPU pero con una velocidad mucho mayor que la E/S del archivo de paginación (incluso en un SSD). Dado que el límite de confirmación se calcula a partir detotalRAM + tamaño del archivo de paginación, no uso de RAM + uso del archivo de paginación, esto no afecta el límite de confirmación. El límite de confirmación no cambia según la cantidad de RAM que se use o para qué se use.
Cuando la carga de confirmación se llena y Windows comienza a pedirme que cierre cosas, la mayor parte del tiempo la memoria física está alrededor del 60%. Esto parece terriblemente ineficiente.
No es que Windows esté siendo ineficiente. Son las aplicaciones que estás ejecutando. Están cometiendo muchos más vas de los que realmente utilizan.
El motivo de todo el mecanismo de "cargo de confirmación" y "límite de confirmación" es el siguiente: cuando llamo a VirtualAlloc, se supone que debo verificar el valor de retorno para ver si es distinto de cero. Si es cero, significa que mi intento de asignación falló, probablemente porque habría provocado que el cargo de confirmación excediera el límite de confirmación. Se supone que debo hacer algo razonable como intentar comprometer menos o salir del programa limpiamente.
Si VirtualAlloc devolvió un valor distinto de cero, es decir, una dirección, eso me indica que el sistema ha garantizado (un compromiso, por así decirlo) que, por muchos bytes que solicite, comenzando en esa dirección,serádisponibles si decido acceder a ellos; que hay algún lugar para guardarlo todo, ya sea la RAM o el archivo de paginación. es decir, no hay razón para esperar ningún tipo de error al acceder a algo dentro de esa región. Eso es bueno, porque no sería razonable esperar que verifique "¿funcionó?" en cada acceso a la región asignada.
La analogía del "banco prestamista de efectivo"
Es un poco como un banco que ofrece crédito, pero estrictamente en efectivo. (Por supuesto, así no es como funcionan los bancos reales.)
Supongamos que el banco comienza con un millón de dólares en efectivo disponible. La gente va al banco y pide líneas de crédito de distintos montos. Digamos que el banco me aprueba una línea de crédito de $100,000 (creo una región privada comprometida); Eso no significa que haya salido efectivo de la bóveda. Si luego pido un préstamo por, digamos, 20.000 dólares (accedo a un subconjunto de la región), eso elimina efectivo del banco.
Pero ya sea que tome algún préstamo o no, el hecho de que me hayan aprobado por un máximo de $100,000 significa que el banco posteriormente solo puede aprobar otros $900,000 en líneas de crédito, en total, para todos sus clientes. El banco no aprobará crédito que exceda sus reservas de efectivo (es decir, no aprobarácomprometerse demasiadoellos), ya que eso significaría que el banco podría tener que rechazar a un prestatario previamente aprobado cuando luego aparezca con la intención de sacarsupréstamo. Eso sería muy malo porque el banco yacomprometidoa permitir esos préstamos, y la reputación del banco se desplomaría.
Sí, esto es "ineficiente" en términos del uso que el banco hace de ese efectivo. Y cuanto mayor es la disparidad entre las líneas de crédito que se aprueban a los clientes y los montos que realmente prestan, menos eficiente es. Pero esa ineficiencia no es culpa del banco; Es "culpa" de los clientes que solicitan líneas de crédito tan elevadas pero sólo obtienen préstamos pequeños.
El modelo de negocio del banco es que simplemente no puede rechazar a un prestatario previamente aprobado cuando se presenta a solicitar su préstamo; hacerlo sería "fatal" para el cliente. Por eso el banco lleva un registro cuidadoso de cuánto del fondo del préstamo se ha "comprometido".
Supongo que expandir el archivo de paginación, o agregar otro, sería como si el banco saliera y obtuviera más efectivo y lo agregara al fondo de préstamos.
Si desea modelar la memoria mapeada y no paginable en esta analogía... la memoria no paginable es como un pequeño préstamo que debe solicitar y conservar cuando abre su cuenta. (Las estructuras no paginables que definen cada nuevo proceso). La memoria mapeada es como llevar su propio dinero en efectivo (el archivo que se está mapeando) y depositarlo en el banco, y luego sacar solo partes de él a la vez (paginarlo). ¿Por qué no enviarlo todo a la vez? No lo sé, tal vez no tengas espacio en tu billetera para todo ese dinero. :) Esto no afecta la capacidad de otros para pedir dinero prestado porque el efectivo que usted depositó está en su propia cuenta, no en el fondo general de préstamos. Esta analogía comienza a fallar allí, especialmente cuando empezamos a pensar en la memoria compartida, así que no la llevemos demasiado lejos.
Volviendo al sistema operativo Windows: el hecho de que tenga gran parte de su RAM "disponible" no tiene nada que ver con el cargo de confirmación y el límite de confirmación. Si está cerca del límite de confirmación, eso significa que el sistema operativo ya se ha comprometido, es decir prometió poner a disposicióncuando se solicita, esa cantidad de almacenamiento. No es necesario que esté todo en uso todavía para que se aplique el límite.
¿Puedo renunciar a inflar artificialmente mi archivo de página a niveles que mi SSD sin espacio no está preparado para manejar solo para poder utilizar efectivamente mi memoria física? (O incluso si no estuviera tan completo. Es decir, me gustaría evitar sugerencias como "Haz X/Y/Z en el archivo de tu página".)
Bueno, lo siento, pero si estás alcanzando el límite de confirmación, solo hay tres cosas que puedes hacer:
- Aumenta tu RAM.
- Aumente el tamaño de su archivo de paginación.
- Ejecute menos cosas a la vez.
Con respecto a la opción 2: puede colocar un segundo archivo de paginación en un disco duro. Si las aplicaciones en realidad no usan toda esa memoria comprometida, lo cual aparentemente no es así, ya que ves tanta RAM libre, en realidad no accederás mucho a ese archivo de paginación, por lo que colocarlo en un disco duro no lo hará. perjudicar el rendimiento. Si la lentitud de un disco duro aún le molesta, otra opción es conseguir un segundo SSD pequeño y, por lo tanto, económico, y colocar en él su segundo archivo de paginación. El único "espectacular" sería una computadora portátil sin posibilidad de agregar una segunda unidad "no extraíble". (Windows no le permitirá colocar archivos de paginación en unidades extraíbles, como cualquier cosa conectada con USB).
Aquí estáotra respuesta que escribieso explica las cosas desde una dirección diferente.
PD: Preguntaste sobre Windows 10, pero debo decirte que funciona de la misma manera en todas las versiones de la familia NT, desde NT 3.1 y también en las versiones preliminares. Lo que probablemente ha cambiado es la configuración predeterminada de Windows para el tamaño del archivo de paginación, de 1,5x o 1x tamaño de RAM a mucho más pequeño. Creo que esto fue un error.