tipo significado reservada palabra negativo long lenguaje ejemplos codigo c#

significado - Encuentra el tamaño de la instancia del objeto en bytes en c#



significado de double en lenguaje c (12)

Para cualquier instancia arbitraria (colecciones de diferentes objetos, composiciones, objetos individuales, etc.)

¿Cómo puedo determinar su tamaño en bytes?

(Actualmente tengo una colección de varios objetos y estoy tratando de determinar el tamaño agregado de la misma)

EDITAR: ¿Alguien ha escrito un método de extensión para Object que podría hacer esto? Eso sería bastante perfecto.


AFAIK, no se puede, sin contar profundamente el tamaño de cada miembro en bytes. Pero, de nuevo, ¿el tamaño de un miembro (como elementos dentro de una colección) cuenta para el tamaño del objeto, o un puntero a ese miembro cuenta para el tamaño del objeto? Depende de cómo lo defines.

Me encontré con esta situación antes, cuando quería limitar los objetos en mi caché en función de la memoria que consumían.

Bueno, si hay algún truco para hacer eso, ¡me encantaría saberlo!


Antes que nada, una advertencia: lo que sigue se encuentra estrictamente en el ámbito de hacks feos e indocumentados. No confíe en que esto funciona, incluso si funciona para usted ahora, puede dejar de funcionar mañana, con cualquier actualización .NET menor o mayor.

Puede usar la información en este artículo sobre las funciones internas de CLR ; la última vez que lo revisé, todavía era aplicable. Así es como se hace esto (recupera el campo interno "Tamaño de instancia básico" a través de TypeHandle del tipo).

object obj = new List<int>(); // whatever you want to get the size of RuntimeTypeHandle th = obj.GetType().TypeHandle; int size = *(*(int**)&th + 1); Console.WriteLine(size);

Esto funciona en 3.5 SP1 de 32 bits. No estoy seguro de si los tamaños de campo son los mismos en 64 bits; es posible que deba ajustar los tipos y / o desplazamientos si no lo están.

Esto funcionará para todos los tipos "normales", para los cuales todas las instancias tienen los mismos tipos bien definidos. Aquellos para los que esto no es cierto son matrices y cadenas de seguridad, y creo también StringBuilder . Para ellos, tendrás que agregar el tamaño de todos los elementos contenidos a su tamaño de instancia base.


Es posible que pueda aproximar el tamaño pretendiendo serializarlo con un serializador binario (pero enrutando la salida al olvido) si está trabajando con objetos serializables.

class Program { static void Main(string[] args) { A parent; parent = new A(1, "Mike"); parent.AddChild("Greg"); parent.AddChild("Peter"); parent.AddChild("Bobby"); System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); SerializationSizer ss = new SerializationSizer(); bf.Serialize(ss, parent); Console.WriteLine("Size of serialized object is {0}", ss.Length); } } [Serializable()] class A { int id; string name; List<B> children; public A(int id, string name) { this.id = id; this.name = name; children = new List<B>(); } public B AddChild(string name) { B newItem = new B(this, name); children.Add(newItem); return newItem; } } [Serializable()] class B { A parent; string name; public B(A parent, string name) { this.parent = parent; this.name = name; } } class SerializationSizer : System.IO.Stream { private int totalSize; public override void Write(byte[] buffer, int offset, int count) { this.totalSize += count; } public override bool CanRead { get { return false; } } public override bool CanSeek { get { return false; } } public override bool CanWrite { get { return true; } } public override void Flush() { // Nothing to do } public override long Length { get { return totalSize; } } public override long Position { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public override int Read(byte[] buffer, int offset, int count) { throw new NotImplementedException(); } public override long Seek(long offset, System.IO.SeekOrigin origin) { throw new NotImplementedException(); } public override void SetLength(long value) { throw new NotImplementedException(); } }


Esto es imposible de hacer en tiempo de ejecución.

Sin embargo, existen varios perfiles de memoria que muestran el tamaño del objeto.

EDITAR : Puede escribir un segundo programa que perfila el primero utilizando la API de generación de perfiles CLR y se comunica con él a través de la comunicación remota o algo así.


Esto no se aplica a la implementación actual de .NET, pero hay que tener en cuenta que el tamaño asignado de un objeto puede cambiar a lo largo de la vida útil del programa con recolecciones de basura / tiempos de ejecución administrados. Por ejemplo, algunos recolectores de basura generacionales (como el colector híbrido de recuento de referencia generacional / posterior) solo necesitan almacenar cierta información después de que un objeto se mueve desde el vivero al espacio maduro.

Esto hace que sea imposible crear una API confiable y genérica para exponer el tamaño del objeto.


Mi clase no se marcó como serializable, por lo que algunas de las respuestas aquí no funcionaron. Lo rodeé así.

var dump = JsonConvert.SerializeObject(obj);


Para cualquiera que busque una solución que no requiera clases [Serializable] y donde el resultado sea una aproximación en lugar de una ciencia exacta. El mejor método que pude encontrar es la serialización json en un flujo de memoria usando la codificación UTF32.

private static long? GetSizeOfObjectInBytes(object item) { if (item == null) return 0; try { // hackish solution to get an approximation of the size var jsonSerializerSettings = new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.IsoDateFormat, DateTimeZoneHandling = DateTimeZoneHandling.Utc, MaxDepth = 10, ReferenceLoopHandling = ReferenceLoopHandling.Ignore }; var formatter = new JsonMediaTypeFormatter { SerializerSettings = jsonSerializerSettings }; using (var stream = new MemoryStream()) { formatter.WriteToStream(item.GetType(), item, stream, Encoding.UTF32); return stream.Length / 4; // 32 bits per character = 4 bytes per character } } catch (Exception) { return null; } }

No, esto no le dará el tamaño exacto que se usaría en la memoria. Como se mencionó anteriormente, eso no es posible. Pero te dará una estimación aproximada.

Tenga en cuenta que esto también es bastante lento.


Para los tipos de valor, puede usar Marshal.SizeOf . Por supuesto, devuelve el número de bytes necesarios para ordenar la estructura en la memoria no administrada, que no es necesariamente lo que utiliza el CLR.


Para tipos no administrados, también conocidos como tipos de valor, structs:

Marshal.SizeOf(object);

Para los objetos administrados, cuanto más cerca tengo es una aproximación.

long start_mem = GC.GetTotalMemory(true); aclass[] array = new aclass[1000000]; for (int n = 0; n < 1000000; n++) array[n] = new aclass(); double used_mem_median = (GC.GetTotalMemory(false) - start_mem)/1000000D;

No use serialización. Un formateador binario agrega encabezados, por lo que puede cambiar su clase y cargar un archivo antiguo serializado en la clase modificada.

Tampoco le indicará el tamaño real en la memoria ni tendrá en cuenta la alineación de la memoria.

[Editar] Al usar BiteConverter.GetBytes (prop-value) recursivamente en cada propiedad de su clase, obtendría los contenidos en bytes, que no cuentan el peso de la clase o las referencias, pero están mucho más cerca de la realidad. Recomendaría usar una matriz de bytes para los datos y una clase de proxy no administrada para acceder a los valores utilizando el puntero si el tamaño importa, tenga en cuenta que no sería memoria alineada, así que en las computadoras viejas va a ser lenta, pero los enormes conjuntos de datos en la RAM MODERNA considerablemente más rápido, ya que minimizar el tamaño para leer de la RAM va a ser un impacto mayor que el desalineado.


Puede usar la reflexión para recopilar toda la información de miembro o propiedad pública (dado el tipo de objeto). Sin embargo, no hay forma de determinar el tamaño sin recorrer cada pieza individual de datos del objeto.



solución segura con algunas optimizaciones CyberSaving / MemoryUsage code . algún caso:

/* test nullable type */ TestSize<int?>.SizeOf(null) //-> 4 B /* test StringBuilder */ StringBuilder sb = new StringBuilder(); for (int i = 0; i < 100; i++) sb.Append("わたしわたしわたしわ"); TestSize<StringBuilder>.SizeOf(sb ) //-> 3132 B /* test Simple array */ TestSize<int[]>.SizeOf(new int[100]); //-> 400 B /* test Empty List<int>*/ var list = new List<int>(); TestSize<List<int>>.SizeOf(list); //-> 205 B /* test List<int> with 100 items*/ for (int i = 0; i < 100; i++) list.Add(i); TestSize<List<int>>.SizeOf(list); //-> 717 B

Funciona también con clases:

class twostring { public string a { get; set; } public string b { get; set; } } TestSize<twostring>.SizeOf(new twostring() { a="0123456789", b="0123456789" } //-> 28 B