Java中的序列化对象大小与内存中对象大小

10
在Java中,是否有一种方法可以从序列化对象的大小粗略估算内存对象的大小?

3
这里大致相似。 - sudmong
可能是估计对象序列化大小的重复问题? - Ciro Santilli OurBigBook.com
2个回答

7
在内存中的大小通常是序列化大小的一半到两倍。最极端的例子可能是Byte,它的序列化大小超过80个字节,在内存中只有16个字节。
您可以使用分析器来告诉您对象使用了多少内存。另一种方法是使用基于 Instrumentation.getObjectSize(object)的工具。
您可能会发现这很有趣 获取对象大小

1
序列化使用标准格式,包括头部、编码的类及其父类。与其阅读关于Java序列化内部表示的指南(我不认为这是一个开放标准),你会通过实践学到更多。 - Peter Lawrey
1
为了做到这一点,您需要知道如何对每个值/字段进行编码,这样您就应该能够计算出编码后的值的大小。这并不会让您知道标题有多大,或者分配的内存对内存对齐的影响。 - Peter Lawrey
1
一个 byte[] 大约使用 12 个字节加上 length。大多数 JVM 都是 8 字节对齐的,因此您需要将其舍入到下一个 8 字节。 - Peter Lawrey
对象序列化规范(包括协议)是一个众所周知的Java文档。不确定“开放标准”与此有何关系。 - user207421
1
@krumpelstiltskin 一个简单的例子是一个字符串,在序列化时使用UTF-8编码。一个长的ASCII字符字符串将会是每个字符1个字节(加上固定大小的头部),然而在内存中它将会是每个字符2个字节(除非使用压缩字符串)。 - Peter Lawrey
显示剩余9条评论

0

这是一个非常好的工具,可以帮助解决这个挑战:

https://github.com/jbellis/jamm

从readme.txt中得知:

MemoryMeter与java.lang.instrument.Instrumentation.getObjectSize一样准确,后者只声称提供“近似”结果,但在实践中似乎能够正常工作。

MemoryMeter使用反射来遍历对象图以进行measureDeep。反射很慢:测量一个包含100万个对象的Cassandra Memtable(即MemoryMeter.countChildren的1百万个子项)需要大约5秒钟的墙钟时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接