zoukankan      html  css  js  c++  java
  • Overhead of a .NET array

    本文摘录自stackoverflow的一个问题overhead-of-a-net-array

    下面列出要点:

    Consider the following code

    var strings = new string[1];
    var ints = new int[1];
    
    strings[0] = "hello world";
    ints[0] = 42;

    Attaching WinDbg shows the following:

    First let's take a look at the value type array.

    0:000> !dumparray -details 017e2acc 
    Name: System.Int32[]
    MethodTable: 63b9aa40
    EEClass: 6395b4d4
    Size: 16(0x10) bytes
    Array: Rank 1, Number of elements 1, Type Int32
    Element Methodtable: 63b9aaf0
    [0] 017e2ad4
        Name: System.Int32
        MethodTable 63b9aaf0
        EEClass: 6395b548
        Size: 12(0xc) bytes
         (C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
        Fields:
              MT    Field   Offset                 Type VT     Attr    Value Name
        63b9aaf0  40003f0        0         System.Int32  1 instance       42 m_value <=== Our value
    
    0:000> !objsize 017e2acc 
    sizeof(017e2acc) =           16 (        0x10) bytes (System.Int32[])
    
    0:000> dd 017e2acc -0x4
    017e2ac8  00000000 63b9aa40 00000001 0000002a <=== That's the value

    First we dump the array and the one element with value of 42. As can be seen the size is 16 bytes. That is 4 bytes for the int32 value itself, 8 bytes for regular reference type overhead and another 4 bytes for the length of the array.

    The raw dump shows the SyncBlock, the method table for int[], the length, and the value of 42 (2a in hex). Notice that the SyncBlock is located just in front of the object reference.

    Next, let's look at the string[] to find out what the additional word is used for.

    0:000> !dumparray -details 017e2ab8 
    Name: System.String[]
    MethodTable: 63b74ed0
    EEClass: 6395a8a0
    Size: 20(0x14) bytes
    Array: Rank 1, Number of elements 1, Type CLASS
    Element Methodtable: 63b988a4
    [0] 017e2a90
        Name: System.String
        MethodTable: 63b988a4
        EEClass: 6395a498
        Size: 40(0x28) bytes <=== Size of the string
         (C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
        String:     hello world    
        Fields:
              MT    Field   Offset                 Type VT     Attr    Value Name
        63b9aaf0  4000096        4         System.Int32  1 instance       12 m_arrayLength
        63b9aaf0  4000097        8         System.Int32  1 instance       11 m_stringLength
        63b99584  4000098        c          System.Char  1 instance       68 m_firstChar
        63b988a4  4000099       10        System.String  0   shared   static Empty
        >> Domain:Value  00226438:017e1198 <<
        63b994d4  400009a       14        System.Char[]  0   shared   static WhitespaceChars
        >> Domain:Value  00226438:017e1760 <<
    
    0:000> !objsize 017e2ab8 
    sizeof(017e2ab8) =           60 (        0x3c) bytes (System.Object[]) <=== Notice the underlying type of the string[]
    
    0:000> dd 017e2ab8 -0x4
    017e2ab4  00000000 63b74ed0 00000001 63b988a4 <=== Method table for string
    017e2ac4  017e2a90 <=== Address of the string in memory
    
    0:000> !dumpmt 63b988a4
    EEClass: 6395a498
    Module: 63931000
    Name: System.String
    mdToken: 02000024  (C:WindowsassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
    BaseSize: 0x10
    ComponentSize: 0x2
    Number of IFaces in IFaceMap: 7
    Slots in VTable: 196

    First we dump the array and the string. Next we dump the size of the string[]. Notice that WinDbg lists the type as System.Object[] here. The object size in this case includes the string itself, so the total size is the 20 from the array plus the 40 for the string.

    By dumping the raw bytes of the instance we can see the following: First we have the SyncBlock, then follows the method table for object[], then the length of the array. After that we find the additional 4 bytes with the reference to the method table for string. This can be verified by the dumpmt command as shown above. Finally we find the single reference to the actual string instance.

    In conclusion

    The overhead for arrays can be broken down as follows (on 32 bit that is)

    • 4 bytes SyncBlock
    • 4 bytes for Method table (type reference) for the array itself
    • 4 bytes for Length of array
    • Arrays of reference types adds another 4 bytes to hold the method table of the actual element type (reference type arrays are object[] under the hood)

    I.e. the overhead is 12 bytes for value type arrays and 16 bytes for reference type arrays.

    参考

    https://www.codeproject.com/Articles/20481/NET-Type-Internals-From-a-Microsoft-CLR-Perspecti

    https://web.archive.org/web/20150515023057/https://msdn.microsoft.com/en-us/magazine/cc163791.aspx

  • 相关阅读:
    Java中存取权限和修饰符public、private、protected和default的区别和联系
    java集合之ArrayList,TreeSet和HashMap分析
    ResultSet,RowSet,OracleCachedRowSet和RowSetMetaData区别及联系
    实战篇
    kubernetes系列之 service代理模式ipvs
    Python Jinja2的简单使用
    Helm v3从入门到实战
    迷宫
    python多线程下载文件
    乱码,编码
  • 原文地址:https://www.cnblogs.com/songqiang/p/overhead-of-a-net-array.html
Copyright © 2011-2022 走看看