什么是内存开销?
当使用的内存超过您创建的字段时。
这是填充吗?
一些是填充,可以出现在对象中的任何位置,但头部始终位于开头。头部通常为8-12个字节长。
JVM压缩指针是什么?
JVM压缩指针是使用32位指针的64位JVM中的一种技术,可节省内存。
这是引用吗?
引用可以使用此技术,但指向对象的类信息的指针也可以使用。
如果使用32位JVM,则开销会更小吗?
可能是,尽管这与对引用和类使用压缩指针相同。
但是这是因为填充吗?
这是因为64位指针使用的空间比32位指针多。
因此,为了内存效率或性能,总是使用32位JVM更好吗?
不是,32位处理器模型具有32位寄存器,而64位模型具有两倍大小(64位)的寄存器,这意味着可以在最快的内存中保存更多的内容。 64位处理模型的计算速度也往往更快。
总的来说,除非您a)无法使用或b)只有很少量的内存,否则建议始终使用64位JVM。
在这个图片中一开始就显示为16字节的JVM开销,为什么?
这并不严格正确。这假定您具有非压缩的类引用,因此标题为12字节,但默认情况下对象是8字节对齐的,这意味着在结尾处会有4字节的填充(总计16字节,但不全在开头)。
常见问题:为什么32位压缩OOP可以寻址超过4GB的空间?
对象默认需要8字节对齐,这样内存管理更加简单但是有时会浪费一些填充。其副作用是每个对象的地址的最低三位都是0(必须是8的倍数)。这些位不需要存储,这就允许压缩OOP可以寻址8*4GB或32GB的空间。
如果采用16字节对齐,JVM可以使用32位引用来寻址64GB的空间(但是填充开销更大,可能不值得这样做)
常见问题:为什么在28-32GB附近速度变慢?
虽然引用可以乘以8,但堆并不从内存的起始位置开始。通常它从4GB之后开始。这意味着如果要使用全部的32GB,则必须添加此偏移量,这会产生轻微的额外开销。
堆大小:
- 小于4GB - 零扩展地址
- 4-28GB - 乘以8或
<< 3
注意:x64有一个指令来支持double[]
和long[]
- 28-32GB - 乘以8并加上保存偏移量的寄存器。稍微慢一些,但通常不是问题。