Java 特定对象列表的内存使用情况
我有一个simplespojo(一个用户类)列表,其中包含大约15个简单字段和1个arrayList。 这些代表用户&可能100或1000个用户将存储在内存中,以避免每次从外部系统检索它们。(我正在使用Ehcache) 我想通过junit测试了解K个用户列表使用了多少内存。 我的直觉是,像这样的简单pojo即使是1000个pojo也不会有任何威胁(换句话说,不到100KO) 提前感谢您的回复。Java 特定对象列表的内存使用情况,java,unit-testing,memory-management,Java,Unit Testing,Memory Management,我有一个simplespojo(一个用户类)列表,其中包含大约15个简单字段和1个arrayList。 这些代表用户&可能100或1000个用户将存储在内存中,以避免每次从外部系统检索它们。(我正在使用Ehcache) 我想通过junit测试了解K个用户列表使用了多少内存。 我的直觉是,像这样的简单pojo即使是1000个pojo也不会有任何威胁(换句话说,不到100KO) 提前感谢您的回复。 非常感谢您的帮助。您可以将它们写入字节输出流,然后获取字节数组并检查其长度。如果您的POJO是可序列化
非常感谢您的帮助。您可以将它们写入
字节输出流
,然后获取字节数组并检查其长度。如果您的POJO是可序列化的,这将起作用 您可以在创建对象之前和之后计算JRE使用的内存,以便估算对象正在使用的字节数
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;
如果需要一个简单的测试,可以将新大小设置为大,然后执行以下操作。 仅当新大小远远大于正在创建的数据时,此选项才有效。 e、 g -XX:NewSize=1g-verbosegc 如果您没有看到任何GC,则该值将是正确的
long before = Runtime.getRuntime().freeMemory();
//build object here
long used = before - Runtime.getRuntime().freeMemory();
注意:这假设您不生成临时对象。有一个实用程序库可以分析对象布局和内存占用
将依赖项添加到项目中(例如使用gradle编译'org.openjdk.jol:jol-core:0.9'
),然后可以使用助手类打印或检查具体对象的内存占用
//打印虚拟机详细信息
System.out.println(VM.current().details());
//创建新对象(这可以是您自己的数据类)
Map o=新的HashMap();
o、 放置(“键1”,123L);
//检查对象大小(例如:从单元测试)
System.out.println(“浅尺寸:+VM.current().sizeOf(o));
System.out.println(“总大小:+GraphLayout.parseInstance(o.totalSize());
System.out.println();
//打印对象详细信息的步骤
System.out.println(ClassLayout.parseInstance(o.toPrintable());
System.out.println(GraphLayout.parseInstance(o.toPrintable());
System.out.println(GraphLayout.parseInstance(o.toFootprint());
本例在Java热点(TM)64位服务器虚拟机(构建25.191-b12,混合模式)上的输出,Java版本“1.8.0_191”
:
为什么要用JUnit测试来实现这一点?这些值很可能取决于JVM版本/供应商/标志和CPU体系结构。对于iNtance,64位Linux上的Sun JVM!=Sun在32位Linux上的JVM!=Sun的JVM在64位Linux上使用CompressedOops。你最好的是个案分析。我也知道这取决于很多事情,但我希望我自己的架构有一些真正的价值&我们在生产中使用的架构。我假设K个使用N字节的简单用户在其他体系结构上的消耗量可能不会超过100倍。非常感谢,Dogbane,这就是我一直在寻找的解决方案。是的。sleep允许GC完成工作,因为它是异步的。简单而优雅!我发现这个解决方案很好——直到我尝试了它。我认为它给出了完全错误的、不可信的结果(为什么…)。多么可悲,听起来如此美妙:''-(
# 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)