在“内存”选项卡中查看时,我有一个具有 8.96 GiB Max Live Size 的类,而 Max Live Count 为 401,000,000。
这是一个 Scala Cons类,它是类型为 LinkedList 的元素Byte
。按照这个逻辑,401M 字节是 401 MiB(可能是某个常数的倍数),所以我不明白为什么实时大小是 8.96 GiB,这要大几个数量级。
有人可以帮我理解这一点吗?
根据Java Object Layout工具实例大小::
或
scala.collection.immutable.$colon$colon
是 24 个字节
➜ java -cp scala-library-2.13.3.jar:jol-cli.jar org.openjdk.jol.Main internals 'scala.collection.immutable.$colon$colon'
# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
# Running 64-bit HotSpot VM.
# Using compressed oop with 3-bit shift.
# Using compressed klass with 3-bit shift.
# WARNING | Compressed references base/shifts are guessed by the experiment!
# WARNING | Therefore, computed addresses are just guesses, and ARE NOT RELIABLE.
# WARNING | Make sure to attach Serviceability Agent to get the reliable addresses.
# 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]
Instantiated the sample instance via public scala.collection.immutable.$colon$colon(java.lang.Object,scala.collection.immutable.List)
scala.collection.immutable.$colon$colon object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 77 0c 02 f8 (01110111 00001100 00000010 11111000) (-134083465)
12 4 java.lang.Object $colon$colon.head null
16 4 scala.collection.immutable.List $colon$colon.next null
20 4 (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
因此
401,000,000 * 24 byte = 9.62 Gigabtye = 8.96 Gigibyte
这是有道理的,因为除了标准对象头之外,::
至少还存储了对头和尾的引用
case class::[+A](head: A, next: List[A])