C # static memory allocation test methods and instance methods

In modular development process, when the non-Code first scene, DML operations directly interact with the database, built-in template code form which DML statements more efficient?

We first memory analysis:

Suppose, to find a data table, the table modular out and configure the current class DML method.

DML is directly written in the subject? Or set a static method in the class? Or extend it? Which is more economical in memory? Thus, there is the following simulation tests:

  1. Pure Class (without DML method, not extended)
  2. Class extension DML method
  3. Examples of Class A method DML built
  4. Class DML built static method
  5. Analog 500,000 objects, memory size and query objects in the form of memory.

According to the network cattle were explained as follows:

Method (Method) a type definition, therefore, it is stored in the Type Object, Type Object is allocated in a particular type of managed heap in the same AppDomain, each type corresponds to a global Type Object. Each instance of a reference type contains a pointer to its immediate Type Object type, each Type Object There is a similar pointer to identify the type of its direct parent Type Object.

When calling the static method, the CLR based method invocation to find the corresponding Type Object, then the method JIT, method after the JIT native code can be run directly, then, this part of the code is loaded into the memory, the method this parameter is loaded into the execution stack, the original address is also recorded execution context to an execution stack; method begins execution after the execution, the execution stack the return address is read out, and then using the local CLR jump instruction to jump to the return to continue.

When calling instance method, the CLR will be to find Type Object pointer of the corresponding instance Type Object, then the method JIT, method after the JIT native code can be run directly, then, this part of the code is loaded into the memory, the examples of parameter objects, and a method is loaded into the current execution stack (instance object is always the first parameter, i.e. the arg0, using ldarg0 read command), the original address is also recorded execution context to an execution stack; method begins execution, after the execution, the execution stack return address is read out, and then using the local CLR jump instruction to jump to the return to continue.

If the method has been JIT off, it will not be a second time JIT.

Methods in IL is in the form of a stream of bytes, so it will still occupy memory.

After the method JIT will be residing in the address space of a process which, therefore, it will occupy memory at runtime.

Metadata is stored in the assembly process and MethodRef MethodDef table.

Define an instance method on a value type is more trouble, we are interested can think about how it performs. Because there is no Type Object pointer value type.

If the value type implements an interface, when the implementation of an interface method implementation even more trouble, we can also think about, welcomed the discussion!

At last,

We all thought that "static method to allocate memory on the heap, an instance method on the stack."

This sentence is completely do not fly, do not be confused. . . As long as that method, it must be in the Type Object, which is to be allocated on the managed heap.

Code:

 

        static void size()
        {
            GC.Collect();
            GC.WaitForFullGCComplete();
            long start = GC.GetTotalMemory(true);
            List<ServerUser2> u2=new List<ServerUser2>();
            for (int i = 0; i < 500000; i++)
            {
                u2.Add(new ServerUser2($"User{i}", true, false, false));
            }
            GC.Collect();
            GC.WaitForFullGCComplete();
            long end = GC.GetTotalMemory(true);
            long size = end - start;
            Console.WriteLine($"纯对象大小:{size}");
            ////////////////////////
            GC.Collect();
            GC.WaitForFullGCComplete();
            start = GC.GetTotalMemory(true);
            List<ServerUser3> u3 = new List<ServerUser3>();
            for (int i = 0; i < 500000; i++)
            {
                u3.Add(new ServerUser3($"User{i}", true, false, false));
            }
            GC.Collect();
            GC.WaitForFullGCComplete();
            end = GC.GetTotalMemory(true);
            size = end - start;
            Console.WriteLine($"扩展对象大小:{size}");
            ////////////////////////
            GC.Collect();
            GC.WaitForFullGCComplete();
            start = GC.GetTotalMemory(true);
            List<ServerUser4> u4 = new List<ServerUser4>();
            for (int i = 0; i < 500000; i++)
            {
                u4.Add(new ServerUser4($"User{i}", true, false, false));
            }
            GC.Collect();
            GC.WaitForFullGCComplete();
            end = GC.GetTotalMemory(true);
            size = end - start;
            Console.WriteLine($"普通方法对象大小:{size}");
            ////////////////////////
            GC.Collect();
            GC.WaitForFullGCComplete();
            start = GC.GetTotalMemory(true);
            List<ServerUser5> u5 = new List<ServerUser5>();
            for (int i = 0; i < 500000; i++)
            {
                u5.Add(new ServerUser5($"User{i}", To true, to false , to false )); 
            } 
            the GC.Collect (); 
            GC.WaitForFullGCComplete (); 
            End = GC.GetTotalMemory ( to true ); 
            size = End - Start; 
            Console.WriteLine ($ " static method object size: size {} " ) ; 

            Console.WriteLine ($ " breakpoint analysis object " ); 
        }
    public class ServerUser2
    {
        [DisplayName("User")]
        public string User { get; set; }
        [DisplayName("Admin")]
        public bool Admin { get; set; }
        [DisplayName("Export")]
        public bool Export { get; set; }
        [DisplayName("Impersonate")]
        public bool Impersonate { get; set; }

        public ServerUser2() { }

        public ServerUser2(string pUser, bool pAdmin, bool pExport, bool pImpersonate)
        {
            User = pUser;
            Admin = pAdmin;
            Export = pExport;
            Impersonate = pImpersonate;
        }


    }

    public class ServerUser3
    {
        [DisplayName("User")]
        public string User { get; set; }
        [DisplayName("Admin")]
        public bool Admin { get; set; }
        [DisplayName("Export")]
        public bool Export { get; set; }
        [DisplayName("Impersonate")]
        public bool Impersonate { get; set; }

        public ServerUser3() { }

        public ServerUser3(string pUser, bool pAdmin, bool pExport, bool pImpersonate)
        {
            User = pUser;
            Admin = pAdmin;
            Export = pExport;
            Impersonate = pImpersonate;
        }


    }


    public class ServerUser4
    {
        [DisplayName("User")]
        public string User { get; set; }
        [DisplayName("Admin")]
        public bool Admin { get; set; }
        [DisplayName("Export")]
        public bool Export { get; set; }
        [DisplayName("Impersonate")]
        public bool Impersonate { get; set; }

        public ServerUser4() { }

        public ServerUser4(string pUser, bool pAdmin, bool pExport, bool pImpersonate)
        {
            User = pUser;
            Admin = pAdmin;
            Export = pExport;
            Impersonate = pImpersonate;
        }
        public bool Insert(DbContext db)
        {
            return db.Database.ExecuteSqlCommand($"INSERT INTO [Server].[ServerUser] ( [User], [Admin], [Export], [Impersonate]) VALUES ( N'{User}', N'{Admin}', N'{Export}', N'{Impersonate}');") > 0;
        }

    }


    public class ServerUser5
    {
        [DisplayName("User")]
        public string User { get; set; }
        [DisplayName("Admin")]
        public bool Admin { get; set; }
        [DisplayName("Export")]
        public bool Export { get; set; }
        [DisplayName("Impersonate")]
        public bool Impersonate { get; set; }

        public ServerUser5() { }

        public ServerUser5(string pUser, bool pAdmin, bool pExport, bool pImpersonate)
        {
            User = pUser;
            Admin = pAdmin;
            Export = pExport;
            Impersonate = pImpersonate;
        }

        public static bool Insert(ServerUser5 item,DbContext db)
        {
            return db.Database.ExecuteSqlCommand($"INSERT INTO [Server].[ServerUser] ( [User], [Admin], [Export], [Impersonate]) VALUES ( N'{item.User}', N'{item.Admin}', N'{item.Export}', N'{item.Impersonate}');") > 0;
        }
    }

    public static class ServerUserDbo
    {
        public static bool Insert(this ServerUser3 item, DbContext db)
        {
            return db.Database.ExecuteSqlCommand($"INSERT INTO [Server].[ServerUser] ( [User], [Admin], [Export], [Impersonate]) VALUES ( N'{item.User}', N'{item.Admin}', N'{item.Export}', N'{item.Impersonate}');") > 0;
        }
    }

 

in conclusion:

Therefore, we can conclude that basically, the case where the same object data, an object that implements the method does not occupy memory addresses, we can understand it in the pointer address is assigned to the heap, it is actually a stack. As long as the same type of class (which may be different instances), the address of the calling method is the same, it is not necessary for the reallocation of memory instances.

    Then the general recommendation on the implementation of the method of how to do it?

    In order to better safeguard the latter, the proposed extension out, so, no matter doing any operation, you can better reuse. Just not particularly good readability.

    However, if written in an instance method, might Class of lines of code and more, convenient maintenance.

Guess you like

Origin www.cnblogs.com/honk/p/12580339.html