Memory usage for a specific list of object

后端 未结 4 1884
别跟我提以往
别跟我提以往 2021-01-03 05:28

i have a list of simples pojos (a User class) with about 15 simple fields & 1 arrayList. Those represent users & maybe 100 or 1000 of them will be store in memory in

相关标签:
4条回答
  • 2021-01-03 05:50

    You can calculate the memory used by the JRE before and after you create your object, in order to approximate how many bytes are being used by your object.

    System.gc();
    System.runFinalization();
    Thread.sleep(1000);
    long before = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    
    //build object here
    
    System.gc();
    System.runFinalization();
    Thread.sleep(1000);
    long after = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    
    long objectSize = after - before;
    
    0 讨论(0)
  • 2021-01-03 05:51

    There is JOL (Java Object Layout) utility library that can analyze object layout and memory footprint.

    Add dependency to your project (for example with gradle compile 'org.openjdk.jol:jol-core:0.9') and then you can use helper classes to print or check memory footprint of concrete object.

    // Print VM details
    System.out.println(VM.current().details());
    
    // Create new object (this can be your own data class)
    Map<String, Long> o = new HashMap<>();
    o.put("key1", 123L);
    
    // To check object size (for example: from unit test)
    System.out.println("Shallow size: " + VM.current().sizeOf(o));
    System.out.println("Total size: " + GraphLayout.parseInstance(o).totalSize());
    System.out.println();
    
    // To print object details
    System.out.println(ClassLayout.parseInstance(o).toPrintable());
    System.out.println(GraphLayout.parseInstance(o).toPrintable());
    System.out.println(GraphLayout.parseInstance(o).toFootprint());
    

    The output of this example on Java HotSpot(TM) 64-Bit Server VM (build 25.191-b12, mixed mode), java version "1.8.0_191":

    # Running 64-bit HotSpot VM.
    # Using compressed oop with 3-bit shift.
    # Using compressed klass with 3-bit shift.
    # Objects are 8 bytes aligned.
    # Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
    # Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
    
    Shallow size: 48
    Total size: 232
    
    java.util.HashMap object internals:
     OFFSET  SIZE                       TYPE DESCRIPTION                               VALUE
          0     4                            (object header)                           01 52 99 6a (00000001 01010010 10011001 01101010) (1788432897)
          4     4                            (object header)                           2d 00 00 00 (00101101 00000000 00000000 00000000) (45)
          8     4                            (object header)                           a3 37 00 f8 (10100011 00110111 00000000 11111000) (-134203485)
         12     4              java.util.Set AbstractMap.keySet                        null
         16     4       java.util.Collection AbstractMap.values                        null
         20     4                        int HashMap.size                              1
         24     4                        int HashMap.modCount                          1
         28     4                        int HashMap.threshold                         12
         32     4                      float HashMap.loadFactor                        0.75
         36     4   java.util.HashMap.Node[] HashMap.table                             [(object), null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]
         40     4              java.util.Set HashMap.entrySet                          null
         44     4                            (loss due to the next object alignment)
    Instance size: 48 bytes
    Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
    
    java.util.HashMap@2d6a9952d object externals:
              ADDRESS       SIZE TYPE                      PATH                           VALUE
            7410cb2b8         24 java.lang.Long            .table[0].value                123
            7410cb2d0    5383088 (something else)          (somewhere else)               (something else)
            7415ed680         48 java.util.HashMap                                        (object)
            7415ed6b0         24 java.lang.String          .table[0].key                  (object)
            7415ed6c8         24 [C                        .table[0].key.value            [k, e, y, 1]
            7415ed6e0         80 [Ljava.util.HashMap$Node; .table                         [(object), null, null, null, null, null, null, null, null, null, null, null, null, null, null, null]
            7415ed730         32 java.util.HashMap$Node    .table[0]                      (object)
    
    
    java.util.HashMap@2d6a9952d footprint:
         COUNT       AVG       SUM   DESCRIPTION
             1        24        24   [C
             1        80        80   [Ljava.util.HashMap$Node;
             1        24        24   java.lang.Long
             1        24        24   java.lang.String
             1        48        48   java.util.HashMap
             1        32        32   java.util.HashMap$Node
             6                 232   (total)
    
    0 讨论(0)
  • 2021-01-03 05:52

    If you want a simple test, you can set the new size to be large and do the following. This only works if your new size is much larger than the data you are creating. e.g.

    -XX:NewSize=1g -verbosegc

    The value will be correct provided you don't see any GC.

    long before = Runtime.getRuntime().freeMemory();
    
    //build object here
    
    long used = before - Runtime.getRuntime().freeMemory();
    

    Note: this assumes you don't generate an temporary objects.

    0 讨论(0)
  • 2021-01-03 06:02

    You can write them to ByteOutputStream, then get byte array and check its length. This will work if your pojos are Serializable.

    0 讨论(0)
提交回复
热议问题