logo

内存

Last Updated: 2023-02-24

入门。

Java 的一个常见问题是 OOM,也就是 Out-of-memory,超内存。一个解决办法是在运行的时候设置更大的内存上限,比如-Xmx31g可将最大内存设为 31GB。

放弃?

有人做了个有趣的实验:如果将-Xms31g -Xmx31g 提高为 -Xms32g -Xmx32g,实际可存储的对象数量反而降低了。

https://blog.codecentric.de/35gb-heap-less-32gb-java-jvm-memory-oddities

进阶!

32-bit 可以存储 2^32,也就是 4 GB 内存的地址;相应的 64-bit 可以存储 2^64 内存地址,代价是要用两倍的 bit 来存储地址。

JVM 中用一个叫 OOP (Ordinary Object Pointer) 的数据结构来表示这个地址。

JVM 中内存按 8-byte 对齐(并不是 Java 的 spec,而是具体 JVM 的实现),所以真正被用到的地址都是 8 的倍数,因而 JVM 发明了 CompressedOops,也就是将地址右移 3 位(也就是除 8),这样相当于 32-bit 可以存储 35-bit 的地址,即 2^35=32GB. 但这是 32-bit 的极限了,如果你想要大于 32GB 的内存,只能用 64-bit 的地址。这就解释了为什么把最大内存从 31G 升到 32G,反而能存储的对象下降了,因为需要更多的地方存地址。