Memory usage for a specific list of object

二次信任 提交于 2020-03-13 06:40:00

问题


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 order to avoid to retrieve them from external system every time. (i'm using Ehcache)

I would like to know with a junit test how much memory is used by a list of K of those users. I have the intuition that simple pojo like those one even for a 1000 ones are not threatening in any way (in other words less than 100 Ko)

Thanks in advance for your anwser. i really appreciate your help.


回答1:


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;



回答2:


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.




回答3:


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




回答4:


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)


来源:https://stackoverflow.com/questions/4802651/memory-usage-for-a-specific-list-of-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!