Is it possible to code the size of the object in memory?

Asked

Viewed 1,461 times

26

If I need to calculate the occupied space to make any decision has how to figure out the size that each type takes to check how much memory will be occupied if I allocate multiple instances of it?

Of course there’s a way to make an account, but I can make a mistake on the account, I can change its structure and not remember to change the total amount where I needed, so I need to find out from the code.

It is also useless to use an external tool because I need the value in the application.

5 answers

26


It depends on what you want. If you want to know the exact size you will occupy it is quite difficult. If you accept an approach there gives, but I do not know if the approach is so useful.

Denis' answer gives an approximation.

Another way is to get the size of the type with the operator sizeof. If you know the object, you know its type. It even works with generics. If you know C, it works the same. Only in C# it is little needed.

The returned value does not include the overhead that each object has to allocate in the heap, if it is the case to allocate there. The account of the overhead is a bit complicated and can vary from version to version, although I’ve never seen change. Today is the size of two CPU words. If you’re in the stack has not overhead, when it’s inside another object in place neither.

Note that if the object contains references, there are other objects that are occupying space as well and it is your problem to detect this and check the entire object graph.

It also complicates when you have array involved, then you have to ask him his size and multiply by the size of the type he carries.

The Runtime does some magic. I don’t know what would happen in cases like this. I can’t trust.

In fact there are so many other things that can influence memory occupation that it is very difficult to know this beforehand.

I don’t like the solution of Arthur, Mathias and LINQ, even if it is the best effort, because it is also inaccurate, you have no control over GC. The allocation is not so linear. If you ask for 4 bytes it won’t change 4 bytes, it can change nothing, it can change more, it depends on the organization of the memory and even how the GC is working in that version. And if you’re in stack will change nothing, so it may seem that the size is 0.

I do not consider any answer here wrong, only there is no precision and this needs to be in the answers to completeza. My opinion.

I guess you’re not talking about unmanaged memory. This can be identified with Marshall.SizeOf().

So my answer is that precisely it does not. Imprecise gives but it does not have much use. . NET is not a suitable platform for this type of thing. If you really need to control the allocation goes from C. Even C++ can complicate some things.

  • The truth is that there is no precise method to return the in-memory size of an object.

  • @Leonancarvalho yes. And I was even researching to see if I ate ball.

  • Highlight for "I do not consider any answer here wrong, only there is no precision and this needs to be in the answers to completeza. My opinion.", fully agree.

12

Directly is not possible.

And I would still say that the . NET does not provide any mechanism in which it is possible to obtain this information precisely.

A good idea, even if subject to failures, is to capture how much the application occupies memory before and after the creation of the object using the method GC.GetTotalMemory() and then subtract the totals.

I used the code below to test and the results were always the same. In the case of the list with 150 thousand items, it remained in 1050544 bytes.

public class Program
{
    public static void Main()
    {
        var memoriaAnterior = GC.GetTotalMemory(true);

        WriteLine(memoriaAnterior);

        var listaEnorme = Enumerable.Range(0, 150000).ToList();

        var memoriaAtual = GC.GetTotalMemory(true);

        WriteLine($"Diferença: { memoriaAtual - memoriaAnterior }");
        ReadLine();
    }
}

9

long size = 0;
object o = new object();
using (Stream s = new MemoryStream()) {
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, o);
    size = s.Length;
}

or

object obj = new List<int>(); // objeto que quer saber o tamanho
RuntimeTypeHandle th = obj.GetType().TypeHandle;
int size = *(*(int**)&th + 1);
Console.WriteLine(size);

This method provides an inaccurate size as it includes information such as: name and DLL version.

Source:

1 - https://stackoverflow.com/questions/605621/how-to-get-object-size-in-memory

2 - https://stackoverflow.com/questions/1128315/find-size-of-object-instance-in-bytes-in-c-sharp

8

I believe it is not possible to measure the size of the object directly, but here in the MSDN they suggested to measure the total memory before and after creating the object, like this:

long tamanho_final = 0;
Objeto meu_objeto;

//Pega o tamanho da memória antes do objeto..
long tamanho_inicial = System.GC.GetTotalMemory(true);
meu_objeto = new Objeto();

//e o tamanho depois da criação
tamanho_final = System.GC.GetTotalMemory(true);
GC.KeepAlive(meu_objeto); //garante que ainda haja uma referência para o objeto na memória


MessageBox.Show(“Tamanho estimado “ + ((long)(tamanho_final – tamanho_inicial)).ToString());

However, there may be some problem/misconception in the calculation if the system uses multiple threads. Apparently if a Thread allocates or frees memory in the process of measuring the size of the object, it can happen that its object gets a negative size (which obviously does not represent a real size), according to some research I did, so maybe it’s not the most viable solution if your system implements multiple threads

8

One way to achieve this size would be to calculate the amount of memory that is used before and after creating the object in the application, this amount can be obtained with the method GC.Gettotalmemory that returns a Int64 with the best rapprochement the number of bytes allocated in memory. As you yourself pointed out in the question, there may be changes in the structure of the object, but I believe that the GetTotalMemory(); takes care not to miscalculate.

ref:How to get Object size in memory?

  • One more good example!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.