实际的内存开销是什么?

Pra*_*mar 8 java jvm memory-management java-memory-model memory-overhead

我读什么-是最内存消耗-的对象-在Java的的什么-是最内存开销的-的对象-在Java的.

但我仍然感到困惑.

  • 什么是内存开销?是padding吗?
  • 什么是JVM压缩指针?是reference吗?
  • 如果32-bit JVM使用,那么开销会减少?当然是.但是因为填充?
  • 那么总是32-bit JVM使用内存效率或性能更好吗?

下图来自此链接(第26页)

在这个图像开始时它们显示为16字节的JVM开销,为什么呢?

在此输入图像描述

Pet*_*rey 8

什么是内存开销?

使用的内存多于您创建的字段.

它是填充物吗?

有些是填充,它可以出现在对象的任何地方,除了总是在开头的标题.标头长度通常为8-12个字节.

什么是带有压缩指针的JVM?

一种在64位JVM中使用32位指针来节省内存的技术.

它参考?

引用可以使用此技术,但也可以指向对象的类信息.

如果使用32位JVM,那么开销会更少?

可能,虽然这与使用参考和类的压缩指针相同.

但这是因为填充吗?

这是因为64位指针比32位指针使用更多的空间.

那么总是使用32位JVM来提高内存效率或性能是否更好?

不,32位处理器型号具有32位寄存器,其中64位型号具有两倍大小(64位)的寄存器,这意味着可以在最快的存储器寄存器中保存更多的寄存器.使用64位处理模型,64位计算也会更快.

一般情况下,我建议您始终使用64位JVM,除非您a)不能或b)拥有非常少量的内存.

在这个图像开始时它们显示为16字节的JVM开销,为什么呢?

这不是严格正确的.这里假设你有一个非压缩的类引用所以标题是12字节,但对象8字节默认对齐,这意味着将有在4个字节的填充(其总计16个字节,但它不是所有在开始)

FAQ:为什么32位压缩OOP的地址超过4 GB

默认情况下,对象必须是8字节对齐的.这使内存管理更容易,但有时会浪费一些填充.副作用是每个对象的地址对于最低的三个比特将具有000(它必须是8的倍数)这些比特不需要存储.这允许压缩的oops处理8*4 GB或32 GB.

使用16字节对象对齐,JVM可以使用32位引用来寻址64 GB(但填充开销较高,可能不值得)

IFAQ:为什么它在 28-32 GB左右变慢

虽然引用可以乘以8,但堆不会在内存开始时启动.它通常在4 GB后开始.这意味着如果您需要完整的32 GB,则必须添加此偏移量,这会产生轻微的开销.

堆大小:

  • <4 GB - 零扩展地址
  • 4 - 28 GB - 乘以8或<< 3注:x64有一条指令支持double[]long[]
  • 28 - 32 GB - 乘以8并添加一个保持偏移量的寄存器.稍慢,但通常不是问题.