Respuesta corta

Respuesta corta

Captura de pantalla de información del sistema de Process Explorer

Esta información del sistema proviene de Process Explorer. Todavía hay memoria física disponible, pero el sistema muestra que casi no queda RAM.

El Administrador de tareas también muestra que se utiliza aproximadamente el 74% de la RAM total.

Desde que instaló Windows 8.1, la computadora tenía 4+8=12 GB de RAM. Lo actualicé cambiando el módulo de 4 GB por un módulo de 8 GB. ¿Podría ser el problema? ¿O es este comportamiento normal y simplemente no he entendido bien el significado de memoria física disponible?

Respuesta1

Respuesta corta

La ventana emergente "sin memoria" dice que se está quedando sin límite deprivado comprometidomemoria: un tipo de memoria virtual. No es que te estés quedando sin RAM (memoria física). No importa cuantodisponibleRAM que tienes. Tener mucha RAM disponible no le permite exceder el límite de confirmación. El límite de compromiso es la suma de tus totalRAM (¡ya sea que esté en uso o no!) más el tamaño actual del archivo de paginación.

Por el contrario, lo que "usa" el límite de confirmación (que es principalmente la creación de espacio de direcciones virtuales privadas para el proceso) no necesariamente usa RAM. Pero el sistema operativo no permitirá su creación a menos que sepa que hay algún lugar para almacenarlo si alguna vez es necesario. Por lo tanto, puede alcanzar el límite de confirmación sin utilizar toda su RAM, o incluso la mayor parte de su RAM.

Es por eso que no debes ejecutar sin un archivo de paginación. Tenga en cuenta que es posible que nunca se escriba en el archivo de paginación. Pero aún así le permitirá evitar los errores de "poca memoria" y "falta de memoria".

Respuesta intermedia

En realidad, Windows no muestra un mensaje de error por quedarse sin RAM. Lo que te estás quedando sin "límite de compromiso".

El gráfico "Sistema" en esa versión de Process Explorer tiene mal nombre. Debería estar etiquetado como "cargo de compromiso". (En la versión que tengo se llama "Confirmación del sistema". Mejor, pero aún no es completamente consistente). En cualquier caso, la altura "actual" del gráfico es lo que se muestra más abajo en la sección de texto como "Cargo de confirmación" - " Actual", y la altura máxima del gráfico representa "Cargo de confirmación" - "Límite".

"Cargo de confirmación" se refiere al espacio de direcciones virtuales respaldado por el archivo de paginación (si tiene uno); en otras palabras, si no cabe todo en la RAM, el resto va al archivo de paginación. (Existen otros tipos de vas que están respaldados por otros archivos, lo que se denomina vas "mapeado") o que deben permanecer en la RAM todo el tiempo; este último se denomina "no paginable".) El "límite de confirmación" es el máximo que el "cargo de compromiso" puede ser. Es igual al tamaño de su RAM más el tamaño del archivo de paginación.

Aparentemente no tiene ningún archivo de paginación (lo sé porque su límite de confirmación es igual al tamaño de su RAM), por lo que el límite de confirmación es simplemente el tamaño de la RAM.

Aparentemente, varios programas + el sistema operativo han utilizado casi todo el compromiso máximo posible.

Esto no tiene nada que ver directamente con la cantidad de RAM disponible o libre. Sí, tienes unos 4,5 GB de RAM disponibles. Eso no significa que puedas exceder el límite de confirmación. La memoria comprometida no necesariamente utiliza RAM y no está limitada por la cantidad de RAM disponible.

Necesita volver a habilitar el archivo de paginación; al utilizar este archivo tan comprometido, sugeriría un archivo de paginación de 16 GB, porque no desea forzar al sistema operativo a mantener tantas cosas en la RAM, y el archivo de paginación funciona mejor si tiene mucho espacio libre, o agregue más RAM. Mucho más. Para un buen rendimiento, necesita tener suficiente espacio en la RAM para el código y otras cosas que no estén respaldadas por el archivo de paginación (pero que se puedan paginar en otros archivos).

Respuesta muy larga

(pero aún es mucho más corto que el capítulo sobre administración de memoria dePartes internas de Windows...)

Supongamos que un programa asigna 100 MB de memoria virtual privada de proceso. Esto se hace con una llamada a VirtualAlloc con la opción "confirmar". Esto dará como resultado un aumento de 100 MB en el "cargo de confirmación". ¡Pero esta "asignación" en realidad no utiliza RAM! La RAM sólo se utiliza cuando parte de esa memoria recién comprometidaespacio de direcciones virtualesSe accede por primera vez.

Cómo se utiliza finalmente la RAM

(si alguna vez lo hace)

El acceso por primera vez al espacio recién comprometido casi siempre sería una escritura en memoria (leer vas privados recién asignados antes de escribirlo es casi siempre un error de programación, ya que su contenido inicial, estrictamente hablando, no está definido). Pero lea o escriba, el resultado, la primera vez que toca una página de vas recién asignado, es unfallo de página. Aunque la palabra "fallo" suena mal, los fallos de página son un evento completamente esperado e incluso necesario en un sistema operativo de memoria virtual.

En respuesta a este tipo particular de error de página, el buscapersonas (parte del administrador de memoria del sistema operativo, que a veces abreviaré como "Mm") hará lo siguiente:

  1. asignar una página física de RAM (idealmente de la lista de páginas cero, pero en cualquier caso proviene de lo que Windows llama "disponible": la lista de páginas cero, libre o en espera, en ese orden de preferencia);
  2. llenar unentrada de la tabla de páginasasociar la página física con la página virtual; y finalmente
  3. descartar la excepción de error de página.

Después de lo cual el código que hizo la referencia a la memoria volverá a ejecutar la instrucción que generó el error de página, y esta vez la referencia se realizará correctamente.

Decimos que la página ha tenido un "error" en el conjunto de trabajo del proceso y en la RAM. En el Administrador de tareas, esto aparecerá como un aumento de una página (4 KB) en el "conjunto de trabajo privado" del proceso. Y una reducción de una página en la memoria física disponible. (Esto último puede ser difícil de notar en una máquina ocupada).

Nota 1:Este error de página no implicó nada leído desde el disco. Una página de memoria virtual comprometida a la que nunca antes se ha accedido no comienza a funcionar en el disco; no tiene lugar en el disco para leerlode. Simplemente se "materializa" en una página de RAM previamente disponible. De hecho, estadísticamente, la mayoría de los fallos de páginas se resuelven en la RAM, ya sea en páginas compartidas que ya están en la RAM para otros procesos, o en las cachés de páginas (las listas en espera o modificadas), o como páginas de "demanda cero" como ésta.

Nota 2:Esto requiere sólo una página, 4096 bytes, de "Disponible". El espacio de direcciones comprometido nunca antes tocado normalmente se realiza (falla) solo una página a la vez, ya que cada página se "toca" por primera vez. No habría ninguna mejora ni ventaja en hacer más a la vez; simplemente tomaría n veces más tiempo. Por el contrario, cuando las páginas deben leerse desde el disco, se intenta cierta cantidad de "lectura anticipada" porque la gran mayoría del tiempo en una lectura de disco se debe a la sobrecarga por operación, no a la transferencia de datos real. La cantidad "comprometida" se queda en 100 MB; el hecho de que una o varias páginas tengan errores no reduce el cargo de confirmación.

Nota 3:Supongamos que tenemos 4 GB de RAM "disponibles". Eso significa que podríamos hacer referencia a la memoria comprometida ya asignada pero a la que nunca antes se hizo referencia aproximadamente un millón de veces más (4 GB/4096) antes de que nos quedáramos sin RAM. En ese momento, si tenemos un archivo de paginación como lo pretendían David Cutler y Lou Perazzoli, algunas de las páginas de la RAM a las que se hizo referencia hace más tiempo se guardarían en el disco y luego estarían disponibles para su uso en la resolución de estas fallas de página más recientes. (En realidad, el sistema operativo iniciaría métodos de recuperación de RAM como "recorte del conjunto de trabajo" antes de eso, y las escrituras reales en el archivo de paginación se almacenan en caché y se agrupan en la lista de páginas modificadas para mayor eficiencia, y y...) Nada de eso afectaría la recuento "comprometido". Sin embargo, es relevante para el "límite de compromiso". Si no hay espacio para toda la memoria "comprometida" en la RAM, el exceso se puede guardar en el archivo de paginación. Por tanto, el tamaño del archivo de paginación contribuye al "límite de confirmación".

Y sigue pasando...

Pero supongamos que no hemos hecho esos millones de referencias más y todavía hay alrededor de 4 GB de páginas "disponibles". Ahora supongamos que el mismo proceso (u otro, no importa) realiza otro VirtualAlloc, esta vez de, digamos, 200 MB comprometidos. Nuevamente, estos 200 MB se agregan al cargo de confirmación y no eliminan ninguna RAM disponible. Simplemente VirtualAlloc'ating espacio de direcciones no utiliza una cantidad correspondiente de RAM, y tener poca RAM "disponible" no limita la cantidad de espacio de direcciones que puede VirtualAlloc (ni tener una alta RAM disponible la aumenta).

(Bueno, está bien... hay un poco de sobrecarga, que equivale a una página (¡paginable!) que se usa para una tabla de páginas por cada 2 MB (4 MB si estás en un sistema x86, no PAE) de espacio de direcciones virtuales asignado y hay un "descriptor de direcciones virtuales" de unas pocas decenas de bytes para cada rango asignado virtualmente contiguo).

De esta manera es posible - ¡y común! - utilizar una gran cantidad de "carga de confirmación" mientras se utilizan sólo pequeñas cantidades de RAM.

Entonces, si "confirmar" el espacio de direcciones virtuales no consume RAM, ¿por qué tiene que haber un límite?

Debido a que el "cargo de compromiso" representa un potencialfuturouso del espacio de almacenamiento. El "límite de confirmación" representa la cantidad total de almacenamiento (RAM + espacio de archivo de paginación) disponible para mantener dichas asignaciones.en caso de que alguna vez se haga referencia a ellos y, por lo tanto, deban almacenarse en algún lugar.

Cuando el Mm aprueba una solicitud de VirtualAlloc, promete - "asumir un compromiso" - que todos los accesos posteriores a la memoria al área asignada tendrán éxito; pueden resultar en fallas de página, pero todas las fallas podrán resolverse, porque HAY almacenamiento adecuado para mantener el contenido de todas esas páginas, ya sea en la RAM o en el archivo de paginación. El Mm lo sabe porque sabe cuánto espacio de almacenamiento hay (el límite de confirmación) y cuánto ya se ha "comprometido" (el cargo de confirmación actual).

(Pero no necesariamente se ha accedido a todas esas páginas todavía, por lo que no necesariamente hay un almacenamiento real que coincida con la cantidad comprometida, en un momento dado).

Entonces... ¿Qué pasa con "el sistema no tiene memoria"?

Si intenta VirtualAlloc y el cargo de confirmación actual más el tamaño de asignación solicitado lo llevaría por encima del límite de confirmación, Y el sistema operativo no puede expandir el archivo de paginación para aumentar el límite de confirmación... obtendrá la ventana emergente "sin memoria". se activa y el proceso ve la llamada de VirtualAlloc FAIL. La mayoría de los programas simplemente se darán por vencidos y morirán en ese punto. Algunos seguirán adelante ciegamente, suponiendo que la llamada tuvo éxito, y fracasarán más tarde cuando intenten hacer referencia a la región que pensaban que habían asignado.

Nuevamente (perdón por la repetición): no importa cuánta RAM disponible tengas. El sistema operativo ha prometido que la RAM o el espacio del archivo de paginaciónvoluntadestará disponible cuando sea necesario, pero esa promesa no resta "Disponible". La RAM disponible solo la utiliza la máquina virtual comprometida cuando estáreferenciadopor primera vez, que es lo que causa que tenga "fallos"... es decir, que se realice en la memoria física. Y simplemente comprometer (= asignar) memoria virtual no hace eso. Solo requiere espacio libre de direcciones virtuales y genera espacio de direcciones virtuales utilizable.

Pero en el caso de "memoria insuficiente", ha habido una solicitud de asignación de memoria comprometida, y el sistema operativo agregó el cargo de confirmación actual al tamaño de esta nueva solicitud... y descubrió que el total esmásque el límite de compromiso. Entonces, si el sistema operativo aprobó este nuevo,yDespués de eso se hizo referencia a todo ese espacio, no habría ningún lugar real (RAM + archivo de paginación) para almacenarlo todo.

El sistema operativo no lo permitirá. En el peor de los casos, no permitirá que se le asignen más vas del espacio que tiene para conservarlo, incluso si todo falla. Ese es el propósito del "límite de compromiso".

Te lo digo tres veces Te lo digo tres veces Te lo digo tres veces:No importa la cantidad de RAM "disponible". No importa que el espacio virtual comprometido no esté utilizando todo ese espacio de almacenamiento todavía. Windows no puede "comprometerse" con la asignación virtual a menos que "pueda" corregir todo en el futuro.

Tenga en cuenta que existe otro tipo de vas llamado "mapeado", que se utiliza principalmente para código y para acceder a archivos de datos de gran tamaño, pero no se cobra por "cargo de confirmación" y no está limitado por el "límite de confirmación". Esto se debe a que viene con su propia área de almacenamiento, los archivos que están "asignados" a ella. El único límite para los vas "mapeados" es la cantidad de espacio en disco que tiene para los archivos mapeados y la cantidad de vas libres en su proceso para asignarlos.

Pero cuando miro el sistema, ¿todavía no he llegado al límite de compromiso?

Se trata básicamente de un problema de medición y mantenimiento de registros. Estás mirando el sistema después de que ya se intentó y falló una llamada a VirtualAlloc.

Supongamos que solo le quedan 500 MB de límite de confirmación y algún programa ha intentado VirtualAlloc 600 MB. El intento fracasa. Luego miras el sistema y dices "¿Qué? ¡Aún quedan 500 MB!" De hecho, puede que quede muchísimo más para entonces, porque es probable que el proceso en cuestión haya finalizado por completo en ese momento, por lo que TODA la memoria comprometida previamente asignada ha sido liberada.

El problema es que no puedes mirar hacia atrás en el tiempo y ver cuál es el cargo de compromiso.eraen el momento en que se realizó el intento de asignación. Y tampoco sabes para cuánto espacio fue el intento. Por lo tanto, no se puede ver definitivamente por qué falló el intento o cuánto más "límite de confirmación" se habría necesitado para permitir que funcionara.

He visto "el sistema escorriendo lentoen la memoria". ¿Qué es eso?

Si en el caso anterior el sistema operativo PUEDE expandir el archivo de paginación (es decir, lo deja en la configuración predeterminada "administrada por el sistema", o lo administra pero establece el máximo en mayor que el inicial, Y hay suficiente espacio libre en el disco), y dicha expansión aumenta el límite de confirmación lo suficiente como para permitir que la llamada a VirtualAlloc tenga éxito, luego... Mm expande el archivo de paginación y la llamada a VirtualAlloc tiene éxito.

Y ahí es cuando ve "el sistema tiene poca memoria". Esta es una advertencia temprana de que, si las cosas continúan sin mitigación, es probable que pronto vea una advertencia de "memoria insuficiente". Es hora de cerrar algunas aplicaciones. Empezaría con las ventanas de tu navegador.

¿Y crees que eso es algo bueno? ¡¡¡La expansión del archivo de paginación es mala!!!

No, no lo es. Mira, el sistema operativo realmente no "expande" el archivo existente. Simplemente asigna una nueva extensión. El efecto es muy parecido al de cualquier otro archivo no contiguo. El contenido del antiguo archivo de paginación permanece exactamente donde está; no es necesario copiarlos a un lugar nuevo ni nada por el estilo. Dado que la mayoría de las E/S de los archivos de paginación se encuentran en fragmentos relativamente pequeños en comparación con el tamaño del archivo de paginación, las posibilidades de que cualquier transferencia determinada cruce un límite de extensión son bastante raras, por lo que la fragmentación no duele mucho a menos que sea realmente excesiva.

Finalmente, una vez que todos los procesos que han "comprometido" espacio en la extensión han cerrado (al cerrar el sistema operativo si no antes), las extensiones se liberan silenciosamente y el archivo de paginación volverá a su tamaño y asignación anteriores; si era contiguo antes, es así de nuevo.

Por lo tanto, permitir la expansión del archivo de paginación actúa como una red de seguridad completamente gratuita: si lo permite pero el sistema nunca lo necesita, el sistema no "expandirá ni contraerá constantemente el archivo de paginación" como se suele afirmar, por lo que costaránada. Y si alguna vez lo necesita, le evitará que las aplicaciones fallen con errores de "falta de memoria virtual".

Pero pero pero...

He leído en docenas de sitios web que si permite la expansión del archivo de paginación, Windows expandirá y contraerá constantemente el archivo de paginación, y que esto resultará en la fragmentación del archivo de paginación hasta que lo desfragmente.

Simplemente están equivocados.

Si nunca ha visto la ventana emergente "quedando poca memoria" (o, en versiones anteriores, "quedando poca memoria virtual"), el sistema operativo nunca ha expandido su archivo de paginación.

Si ve esa ventana emergente, eso le indica que el tamaño de su archivo de paginación inicial es demasiado pequeño. (Me gusta configurarlo en aproximadamente 4 veces el uso máximo observado; es decir, el contador de rendimiento "% pico de uso del archivo de paginación" debe estar por debajo del 25%. Motivo: el espacio del archivo de paginación se administra como cualquier otro montón y funciona mejor con mucho espacio libre para jugar.)

Pero ¿por qué no simplemente...?

Se podría argumentar que el sistema operativo debería simplemente dejar que se realice la asignación y luego dejar que elreferenciasfalla si no hay RAM disponible para resolver los fallos de la página. En otras palabras, arriba donde describimos cómo funciona la falla de la página inicial, ¿qué pasa si "asignar una página física disponible de RAM" (paso 1) no se puede hacer porque no había ninguna disponible?y¿No quedaba ningún lugar para publicar nada y ponerlo a disposición?

Entonces el buscapersonas no podrá resolver el error de la página. Tendría que permitir que la excepción (el error de la página) se informe al hilo defectuoso, probablemente cambiado a algún otro código de excepción.

La filosofía de diseño es que VirtualAlloc devolverá cero (técnicamente un puntero NULL) en lugar de una dirección si se agota el límite de confirmación, y es completamente razonable esperar que el programador sepa que una llamada a VirtualAlloc puede fallar. Por lo tanto, se espera que los programadores verifiquen ese caso y hagan algo razonable en respuesta (como darle la oportunidad de guardar su trabajo hasta ese punto y luego finalizar el programa "con elegancia"). (Programadores: verifican si hay un retorno de puntero NULL de malloc, new, etc., ¿sí? Entonces, ¿por qué no lo harías con esto?)

Pero los programadores no deberían esperar que una simple referencia de memoria como

i = 0;             // initialize loop counter

podría fallar, no si se encuentra en una región de espacio de direcciones comprometido exitosamente. (O espacio de direcciones mapeado, para el caso). Pero eso es lo que podría suceder si se siguiera la filosofía de "permitir la asignación excesivamente comprometida, dejar que la referencia de memoria falle".

Desafortunadamente, una referencia de memoria como la de la línea de código anterior simplemente no tiene una forma conveniente de devolver un estado incorrecto. Se supone que solo debentrabajar, al igual que la suma y la resta. La única manera de informar tales fallas sería como excepciones. Entonces, para manejarlos, el programador tendría que envolver todo el programa en un controlador de excepciones. (intenta... atrapar y todo eso.)

Eso se puede hacer... Pero sería difícil para el controlador saber cómo "hacer lo correcto" en respuesta a esas excepciones, ya que habría muchísimos puntos en el código donde podrían surgir. (Específicamente, podrían surgir encadareferencia de memoria a la memoria VirtualAlloc, a la memoria asignada con malloc o new... y también a todas las variables locales, ya que la pila también está VirtualAlloc).

En resumen, hacer que el programa fracase satisfactoriamente en estos casos sería muy difícil.

Por otro lado, es bastante fácil verificar si VirtualAlloc devuelve un puntero NULL (o malloc o new, aunque no son exactamente lo mismo) y luego hacer algo razonable... como no intentar ir continuar y hacer aquello para lo que el programa necesitaba ese espacio virtual. Y tal vez preguntarle al usuario si desea guardar su trabajo hasta el momento, si corresponde. (Es cierto que hay demasiadas aplicaciones que ni siquiera se molestan en hacer tanto).

Otros usuarios de compromiso

Por cierto, el "límite de confirmación" no se reduce por las diversas asignaciones del sistema operativo, como el grupo paginado y no paginado, la lista PFN, etc.; a estos solo se les cobra para cometer cargos a medida que suceden. El cargo de confirmación o el límite de confirmación tampoco se ven afectados por la RAM de video, ni siquiera por el tamaño de la "ventana" de RAM de video.

Pruébalo tú mismo

Puede hacer una demostración de todo esto con la herramienta testlimit del sitio SysInternals. La opción -m asignará espacio de direcciones comprometido pero no lo "tocará", por lo que no provocará la asignación de RAM. Mientras que la opción -d asignará y también hará referencia a las páginas, lo que provocará que la carga de confirmación aumente y la RAM disponible disminuya.

Referencias

Partes internas de Windowspor Russinovich, Solomon y Ionescu. Incluso hay demostraciones que le permiten demostrar todos estos puntos utilizando la herramienta testlimit. Sin embargo, debo advertirles que si creen que esto fue largo, estén advertidos: solo el capítulo de Mm tiene 200 páginas; lo anterior es una versión EXTREMADAMENTE simplificada. (Consulte también la sección "Agradecimientos" en la Introducción).

Ver tambiénDocumentación de MSDN VirtualAlloc

Respuesta2

Tal vez para sumarla brillante respuesta aceptada:

Windows y la mayoría de los programas asumen que pueden asignar tanta memoria (virtual) como sea necesaria. Esta es una de las grandes razones por las que no se debe desactivar el archivo de paginación, consulte la propuesta.hecho 2.2enmi pregunta de superusuario.

También me enlace aesta brillante respuesta de error del servidorallí, lo que deja claro cómo funciona el archivo de paginación:

Mucha gente parece suponer que Windows inserta datos en el archivo de paginación según demanda. Por ejemplo: algo quiere mucha memoria y no hay suficiente RAM para satisfacer la necesidad, por lo que Windows comienza a escribir datos de la RAM en el disco alocadamente en este último minuto, para poder liberar RAM para las nuevas demandas.

Esto es incorrecto. Hay más cosas sucediendo bajo el capó. En términos generales, Windows mantiene unalmacén de respaldo, lo que significa que quiere ver todo lo que está en la memoria y también en algún lugar del disco. Ahora, cuando surge algo que exige mucha memoria, Windows puede borrar la RAM muy rápidamente, porque esos datos se almacenan.yaen el disco, listo para ser paginado nuevamente en la RAM si es necesario. Por tanto, se puede decir que gran parte de lo que hay en el archivo de paginación también está en la RAM; los datos fueronpreventivamentecolocado en el archivo de paginación para acelerar las nuevas demandas de asignación de memoria.

Otras lecturasestá provistoaquí

información relacionada