Red de conocimiento informático - Conocimiento informático - Cómo reducir el uso de memoria de los programas de Windows

Cómo reducir el uso de memoria de los programas de Windows

Mi SetProcessWorkingSetSize funciona

Lo siguiente es de:

Entonces, ¿cómo es posible que mi programa mueva la memoria que ocupa a la memoria virtual?

De hecho, también puede intentar minimizar un programa en la barra de tareas y luego mirar el administrador de tareas y encontrará que la memoria real ocupada por su programa ha disminuido repentinamente. que tengo una forma de comprimir la memoria, pero el propio sistema operativo tiene este mecanismo, es decir, cuando el programa no está en uso (minimizado), el sistema operativo llamará a ciertos comandos para transferir la memoria ocupada por el programa. a la memoria virtual, solo se usa la memoria virtual y solo se usa la memoria virtual ocupada por el programa.

Entonces, tenemos esta situación en la que la huella de memoria se reduce instantáneamente.

Entonces: ¿Qué instrucciones llama el sistema? ¿Es posible liberar memoria sin reducirla?

Vea esta API SetProcessWorkingSetSize

Extraído de MSDN

El uso de la función SetProcessWorkingSetSize para establecer el tamaño mínimo y máximo del conjunto de trabajo de la aplicación no garantiza lo solicitado La memoria se conservará o permanecerá residente en todo momento. Cuando una aplicación está inactiva o un conjunto de memoria bajo no está disponible, la aplicación no puede usar la memoria solicitada.

Cuando una aplicación está inactiva o una condición de poca memoria causa demandas de memoria, el sistema operativo puede reducir el conjunto de trabajo de la aplicación o puede usar la función VirtualLock para bloquear el rango de espacio de direcciones virtuales de la aplicación en la memoria. ; Sin embargo, esto puede reducir el rendimiento del sistema. Cuando una aplicación está inactiva o la memoria del sistema es demasiado baja, el sistema operativo llama automáticamente a este mecanismo para configurar la memoria de la aplicación. Las aplicaciones también pueden usar VirtualLock para bloquear un rango de memoria, evitando que el sistema la libere.

Cuando aumentas el tamaño del conjunto de trabajo de una aplicación, consumes memoria física de otras partes del sistema. Esto puede reducir el rendimiento de otras aplicaciones y del sistema.

Cuando aumentas el tamaño del conjunto de trabajo de una aplicación, consumes memoria física de otras partes del sistema. Esto también puede provocar que fallen las operaciones que requieren memoria física, como la creación de procesos, subprocesos y grupos de kernel.

Cuando aumenta el tamaño del espacio de ejecución de una aplicación, la cantidad de memoria física que obtiene depende del sistema, lo que puede reducir el rendimiento de otras aplicaciones o del sistema en general, y también puede resultar en la necesidad para físico La operación de la memoria falló. Esto también puede provocar que fallen las operaciones que solicitan memoria física, como la creación de procesos, subprocesos y grupos de núcleos, por lo que se debe utilizar con precaución.

========================

De hecho, usar esta función no mejorará mucho el rendimiento. y realmente no ahorrará memoria.

Porque solo mueve temporalmente la memoria ocupada por la aplicación a la memoria virtual, y luego cada vez que la aplicación se activa o solicita una operación, la memoria virtual se ocupará nuevamente. Si fuerza este método para configurar la memoria ocupada por una aplicación, puede reducir el rendimiento del sistema hasta cierto punto porque el sistema necesita realizar frecuentes intercambios de páginas entre la memoria y el disco duro.

BOOL SetProcessWorkingSetSize(

HANDLE hProcess,

SIZE_T dwMinimumWorkingSetSize,

SIZE_T dwMaximumWorkingSetSize

);

p>

Establecer ambos parámetros TAMAÑO_T en -1 permite que el proceso intercambie la memoria que usa en memoria virtual, dejando solo una pequeña porción del código

Y debido al uso de temporizadores, Desktop Calendar Show Al poder mantener una cantidad mínima de memoria en todo momento, ya que el temporizador lo hace continuamente, el rendimiento es predecible, aunque la ilusión de pequeñas cantidades de memoria intercambiadas puede ser un verdadero desastre para el sistema.

Por supuesto, esta función no está exenta de defectos,

1.

2. Cuando nuestra aplicación acaba de terminar de cargarse, podemos usar esta operación una vez para colocar el código que no es necesario durante el proceso de carga en la memoria virtual, de modo que una vez que el programa complete la carga, una gran cantidad. de código se conservará.

3. Después de que el programa haya estado ejecutándose durante un período de tiempo, o cuando el programa esté a punto de quedar inactivo, puede usar este comando para intercambiar la memoria ocupada en memoria virtual.

Finalmente, adjunte el código API llamado por VB

Opción explícita

Función de declaración privada SetProcessWorkingSetSize Lib "kernel32" (ByVal hProcess As Long, ByVal dwMinimumSetSize Lib " kernel32").ByVal dwMinimumWorkingSetSize mientras, ByVal dwMaximumWorkingSetSize mientras) mientras

Función de declaración privada GetCurrentProcess Lib " kernel32" () mientras

SetProcessWorkingSetSize GetCurrentProcess, -1, -1

Devuelve la memoria utilizada por el proceso actual como 0. Colóquelo en la ubicación adecuada

2. Distinga entre memoria física, memoria virtual, conjunto de trabajo (memoria) y memoria

El siguiente contenido proviene de:

Esta pregunta ha aparecido muchas veces en CSDN, y cada vez solo di una respuesta simple: No haga referencia a los datos de uso de memoria del Administrador de tareas. El tamaño de los datos no tiene un impacto directo en el rendimiento del programa.

Las siguientes son algunas de mis ideas sobre el análisis de este problema. Espero que sean útiles para quienes estén interesados ​​en este problema.

P: ¿Está solo .NET?

Respuesta: ¡No! Como dijo Saucer anteriormente, esto no es un problema de .NET, todos los programas de Windows se comportan de manera similar. Por ejemplo, el siguiente programa en C:

void main { while(1 } //dead loop. //bucle infinito para que podamos ver el administrador de tareas

En mi máquina el uso de memoria en la ejecución inicial fue de 632K, y cuando minimizé la consola y la restauré el uso de memoria es de 36K. Aparentemente, esto no es un problema específico de .NET, sino más bien un problema de administración de memoria de Windows.

P: ¿Cuánta memoria utiliza mi programa?

Respuesta: No es fácil responder a esta pregunta.

Comencemos con algunos conceptos básicos de la administración de la memoria virtual del sistema operativo: cada proceso de Windows tiene 4G de espacio de direcciones, pero su máquina obviamente no tiene 4G de memoria física. En un entorno multitarea, la memoria total utilizada por todos los procesos puede exceder la memoria física de la computadora. En algunos casos, parte de un proceso puede eliminarse de la memoria física y almacenarse en un archivo de paginación en el disco duro. Cuando un proceso intenta acceder a la memoria intercambiada en el archivo de paginación, el sistema genera un error de página y el Administrador de memoria de Windows es responsable de llamar la página correspondiente desde el disco duro a la memoria física. El Administrador de memoria de Windows es responsable de llamar las páginas de memoria correspondientes desde el disco duro a la memoria física.

En un momento dado, la memoria física a la que el proceso puede acceder directamente (sin fallas de página) se denomina conjunto de trabajo del proceso y la memoria que el proceso realmente asigna (envía) desde la dirección 4G; El espacio al que se puede acceder se denomina memoria virtual comprometida. La memoria virtual comprometida puede existir en el archivo de página, mientras que el conjunto de trabajo debe residir en la memoria física.

Entonces, para responder a la pregunta anterior, primero debemos preguntarnos: ¿De qué estás hablando? ¿Memoria física o memoria comprometida?

Pregunta: ¿Qué son los datos de "uso de memoria"?

Respuesta: De la Ayuda del Administrador de tareas: En el Administrador de tareas, los datos de "Uso de memoria" son los datos de "Uso de memoria". Ayuda del administrador: en el Administrador de tareas, el conjunto de trabajo actual del proceso, en kilobytes.

El nombre "Uso de memoria" es algo engañoso. Solo representa la memoria física ocupada actualmente por el proceso, es decir, el conjunto de trabajo. WorkingSet no representa toda la memoria virtual actualmente "ocupada" por el proceso; es posible que el proceso tenga algunos datos intercambiados en el archivo de paginación. Sólo cuando se accede a estos datos se cargan en la memoria física.

También hay una columna en el Administrador de tareas, Tamaño de VM, que representa la cantidad de memoria visual comprometida asignada al proceso. La definición real es un poco más complicada que esto, pero es suficiente para el problema. queremos analizar. Tomando el programa C anterior como ejemplo, el tamaño de la VM antes y después de la minimización es 176K y no ha cambiado.

Así que la conclusión es simple: cuando se minimiza un programa de Windows, el Administrador de memoria de Windows minimizará el conjunto de trabajo del proceso (basado en FIFO o LRU usado menos recientemente) e intercambiará la mayoría de los datos al archivo de paginación intermedio. . Esto es fácil de entender: normalmente siempre queremos dejar más memoria física para que el programa en primer plano obtenga un mejor rendimiento. Cuando un programa se reanuda desde un estado minimizado, Windows no carga completamente toda la memoria virtual del programa, sólo las partes necesarias. Esto también es fácil de entender: rara vez se accede al código en la fase de inicio del programa después del inicio (esto es especialmente cierto para los programas .NET, si no se usa Reflection después de que el programa se carga normalmente, los módulos como Fusion generalmente no se usan). usado).

P: Entonces, ¿necesitamos un conjunto de trabajo más pequeño o uno más grande? La sabiduría convencional nos dice: cuanto más pequeño, mejor.

Respuesta: Depende de la situación específica. Si el conjunto de trabajo es demasiado pequeño, se producirá una gran cantidad de interrupciones fuera de página cuando el programa se esté ejecutando, lo que afectará gravemente el rendimiento del programa. Por otro lado, si el conjunto de trabajo es demasiado grande, se desperdiciará una memoria física "valiosa", reduciendo así el rendimiento de todo el sistema. En general (a menos que sea una aplicación muy sensible al rendimiento y esté muy familiarizado con la administración de memoria de Windows), se recomienda no ajustar el tamaño del conjunto de trabajo en el programa en sí, sino dejar esta tarea al Administrador de memoria de Windows. Saucer presenta cómo hacer esto: ();

Pregunta: Última pregunta, ¿mi programa realmente ocupa tanta memoria física?

Respuesta: Esta pregunta puede ser un poco cliché: el número está claramente escrito en el Administrador de tareas.

Después de comprobar con vadump, se descubrió que la razón principal de la reducción en el proceso WorkingSet era que una gran cantidad de archivos DLL no se cargaban en la memoria física al recuperarse de la minimización. Sabemos que una de las características de las bibliotecas de enlaces dinámicos es el uso compartido de código. Tomando como ejemplo NTDLL.DLL, casi todas las aplicaciones en todo el sistema Windows (específicamente, todos los programas en el subsistema Win32) necesitan hacer referencia a NTDLL, si es que todas. Si el programa tuviera una copia, ese archivo por sí solo ocuparía decenas de megabytes de memoria. La solución de Windows es mantener solo una copia de NTDLL.DLL en la memoria física. Todos los programas que hacen referencia a la DLL asignarán la copia a su propio espacio de memoria y disfrutarán del segmento de código de NTDLL.DLL (cada proceso Los segmentos de datos siguen siendo independientes. ). Entonces, si bien el tamaño de NTDLL.DLL se tiene en cuenta en el conjunto de trabajo de su programa, eliminar la referencia a esa DLL de su programa en realidad no libera mucha memoria física porque usted no la está usando, ¡pero otros sí la están usando!

Por lo tanto, la memoria física "exclusiva" de su programa es mucho menor de lo que muestra el uso de memoria, y necesita restar una gran cantidad de páginas de códigos compartidos del uso de memoria (como puede ver en vadump).

¿Conclusión? No haga referencia a los datos de uso de memoria del Administrador de tareas; el tamaño de estos datos no tiene un impacto directo en el rendimiento del programa. Es más fácil y preciso utilizar los contadores relacionados con .NET de Perfomence Monitor.