c# - sistema - proceso de encendido de una computadora
¿Dónde se mantiene el búfer de objeto<MyClass>? ¿Está en RAM o HDD? (4)
Al especular con su escasa descripción, hay dos tipos de cosas que tal vez no se dé cuenta:
El uso de 15-16 MB que ve puede no tener nada que ver con el tamaño de su lista: podrían ser los requisitos de memoria para el resto del programa, y su lista solo consume una cantidad insignificante de memoria en comparación. Incluso si no crea objetos de forma explícita, su programa todavía tiene que cargar bibliotecas y cosas, lo que requiere memoria.
No sé C #, así que no sé si esto se aplica a la
List
, pero una de las implementaciones de clase de contenedor estándar para asignar dinámicamente una matriz para contener los objetos ... y si la matriz se llena alguna vez, entonces asigna una la nueva matriz duplica el tamaño y copia todo sobre la nueva matriz y continúa (la proporción real puede ser diferente a $ 2 $). Esto puede tener el efecto de que el uso de la memoria permanezca constante durante un tiempo prolongado, hasta que finalmente llene la matriz y luego, de repente, aumente de tamaño, solo para permanecer constante de nuevo durante mucho tiempo.
Mi pregunta puede sonar un poco vaga. Pero lo que quiero saber es dónde se mantiene el búfer List<>
.
Tengo una lista List<MyClass>
a la que estoy agregando elementos de un bucle infinito. Pero el consumo de RAM del Servicio de Windows (dentro del cual estoy creando la Lista) nunca supera los 17 MB. De hecho, oscila entre 15 y 16 MB, incluso si continúo agregando elementos a la Lista. Estaba tratando de hacer algunas pruebas de carga de mi servicio y me encontré con esto.
¿Alguien puede decirme si descarga los datos a alguna ubicación temporal en la máquina y los selecciona desde allí ya que no veo un aumento en el consumo de RAM?
El método que estoy llamando infinitamente es AddMessageToList ().
class MainClass
{
List<MessageDetails> messageList = new List<MessageDetails>();
private void AddMessageToList()
{
SendMessage(ApplicationName,Address, Message);
MessageDetails obj= new MessageDetails();
obj.ApplicationName= ApplicationName;
obj.Address= Address;
obj.Message= Message;
lock(messageList)
{
messageList.Add(obj);
}
}
}
class MessageDetails
{
public string Message
{
get;
set;
}
public string ApplicationName
{
get;
set;
}
public string Address
{
get;
set;
}
}
En general, los objetos de C # se crean a partir del montón, que reside en la memoria. Si desea almacenar cosas en el disco, hay maneras de hacerlo, pero una List<T>
estándar List<T>
vivirá en la memoria.
Cuando cree un objeto, ocupará un cierto número de bytes en la memoria más el tamaño de los punteros que se utilizan para hacer referencia a él. Agregarlo a una lista solo agrega un puntero al objeto que ya ha creado, por lo que si agrega muchas copias de la misma instancia a la lista, no crecerá tan rápido como espera.
Si realmente quieres probar el impacto de las grandes estructuras de datos en tu memoria, tendrás que aumentar los números. Unos pocos miles de objetos promedio no van a ocupar mucha memoria, pero unos pocos millones podrían.
También te puede interesar el método GC.GetTotalMemory()
y sus amigos.
La respuesta a tu pregunta es: "En memoria".
Eso puede significar RAM, y también puede significar el disco duro (Memoria virtual). El administrador de memoria del sistema operativo decide cuándo colocar la memoria en la memoria virtual, que en su mayoría tiene que ver con la frecuencia con la que se accede a la memoria (aunque no pretendo conocer el algoritmo específico de Microsoft).
También preguntaste por qué tus usos de memoria no aumentan. En primer lugar, un MegaByte es una enorme cantidad de memoria. A menos que su clase sea bastante grande, necesitará MUCHOS de ellos para que aparezca un MB. Eventualmente, el uso de la memoria debería aumentar.
Tenga en cuenta que casi toda la memoria en Windows (y .NET) es memoria virtual: su ubicación "real, física" es arbitraria, la administración de memoria de Windows se encarga de eso. Sin embargo, independientemente de si actualmente está utilizando RAM física o un archivo de página en el disco duro, se mostrará como memoria privada confirmada.
Por lo tanto, depende de cómo esté creando realmente los elementos y agregándolos a la List<T>
. ¿Cuántos objetos hay? ¿Está agregando el mismo objeto una y otra vez, o creando uno nuevo cada vez? ¿Está utilizando la misma instancia de lista o está creando otras? ¿Mantiene referencias a los objetos creados (y listas de instancias), o los está tirando? ¿Realmente haces algo con el objeto / lista? De lo contrario, el optimizador podría haber eliminado el código por completo (aunque es muy conservador, por lo que no contaría con eso al agregar elementos a una lista; es un escenario muy complejo con posibles efectos secundarios).
En el caso ideal de memoria más baja, podría estar usando aproximadamente cuatro bytes por elemento de la lista, eso no es mucho: ¡necesitaría 262 144 elementos para consumir un solo MiB de memoria!
Muéstranos tu código, todo el bucle y su entorno. Entonces podemos decirte lo que realmente estás haciendo.
EDIT : esto es en un servicio WCF? Deberías haberlo dicho antes. ¿Dónde almacena la clase MainClass
? Si está dentro de la clase de servicio WCF, puede que no dure más que una sola solicitud. E incluso si lo arreglas y lo guardas en algo un poco más persistente, como una clase estática, entras en la complejidad de cuándo se recopila todo, cómo se reinicia el servicio, etc. Si necesitas que los datos se retengan de forma segura. durante más tiempo que una sola solicitud, almacenarla en la memoria de proceso no es suficiente. Si no le importa que los datos se desechen de vez en cuando, puede hacer que la instancia de la List
estática (de lo contrario, no se compartirá ni persistirá). De lo contrario, utilice una base de datos.