在哪里可以找到如何计算java对象大小的证据

daw*_*tar 2 java memory size jvm object

我已经搜查约了很久的Java对象的大小,也有很多类似的答案这样,每个人都告诉我,一个Java对象的开销的大小,以及如何计算出来的实际大小.但他们怎么知道呢?我没有从官方的oracle文件中找到任何证据.这个结论有什么证据?或者数据来自一些基于某些实验的猜测?

另一件事.据官方文档,有一个"近似"的方式来测量物体中提到-的仪表方式,任何人可以向我解释什么是"约"的意思?什么时候准确,什么时候不准确.最好有证据.

Pet*_*rey 5

如何计算出实际尺寸.但他们怎么知道呢?

来自经验.

我没有从官方的oracle文件中找到任何证据.

它取决于JVM.对于基于OpenJDK的JVM,32位JVM具有与64位JVM不同的标头大小,因为标头包含引用.其他JVM可能会再次出现不同.

或者数据来自一些基于某些实验的猜测?

基本上,是的.

任何人都可以向我解释什么是"近似"的意思?

当您测量对象的大小时,它可能意味着许多不同的东西

  • 物体有多大?(浅景深)
  • 它使用了多少内存?(对象分配是8字节对齐,即总是8的倍数)
  • 对象和引用的所有对象使用了多少空间?(深度)
  • 丢弃后可以释放多少空间?(共享多少个对象,它出现在释放内存的两个片段的中间)
  • 您是否计算堆栈上使用的空间或堆内存中使用的空间?

根据您需要了解的内容,您可以获得许多不同的答案,有一个数字与您用于计算的所有数字大致接近是很有用的.


使用Runtime遇到问题的地方是TLAB在大块中分配数据.可以以多线程方式进一步分配这些大块.缺点是你没有获得准确的内存使用信息.

static long memTaken() {
    final Runtime rt = Runtime.getRuntime();
    return rt.totalMemory() - rt.freeMemory();
}

public static void main(String... args) {
    long used1 = memTaken();
    Float i = new Float(0);
    long used2 = memTaken();
    System.out.println("new Float(0) used "+(used2 - used1)+" bytes.");
}
Run Code Online (Sandbox Code Playgroud)

无选择地运行

new Float(0) used 0 bytes.
Run Code Online (Sandbox Code Playgroud)

关闭TLAB,你看到了 -XX:-UseTLAB

new Float(0) used 336 bytes.
Run Code Online (Sandbox Code Playgroud)

这比你想象的要高得多,因为必须加载类本身.如果首先通过添加到开始创建一个Float实例

Float j = new Float(1);
Run Code Online (Sandbox Code Playgroud)

你得到

new Float(0) used 16 bytes
Run Code Online (Sandbox Code Playgroud)