0

大家下午好

我有一个看起来像这样的类:

public class Grapheme {
    public Grapheme(int[] code_points) {
        this.code_points = code_points;
    }
    int[] code_points;
}

从下面 bdonlan 提供的链接中了解到通常一个 Grapheme 对象需要 8 个字节的对象头,4 个字节的变量(其类型是reference)和 4 个字节的填充。code_points

因此,如果我使用代码创建 Grapheme 实例,则new Grapheme(null)该 Grapheme 实例通常总共需要 16 个字节。由于它是否为 16 字节是特定于实现的,从这里开始,我将把这个数字称为x字节。

基本上我想知道我是否创建了n个 Graphemes,将它们传递null给构造函数,并将这些 Graphemes 存储到长度为nGrapheme(int[])的数组中,

运行时(存储 Grapheme 实例)所需的总内存是否严格 为 n * x字节?

或者 JVM 有没有机会尝试做一些神奇的优化,使得所需的内存低于n * x字节?

4

1 回答 1

2

不,对象的大小是固定的。考虑一下 - 如果 JVM 确实将您的 Graphemes 打包成一个数组,它们之间没有空格,如果某些代码更改了code_points稍后的值会发生什么?它必须移动所有其他字形,并重写任何指向它们的指针。这将是一个巨大的性能损失(你可能需要执行一次完整的 GC 来重写所有这些指针......),并且对于试图弄清楚为什么一个简单的赋值如此缓慢的程序员来说是完全难以理解的。所以 JVM 不做这种优化。

另请注意,您的开销估计有点偏离。根据这个页面,对象有 8 个字节的开销,加上任何内部字段的空间,为 12 个字节。然后将其四舍五入为 8 字节的倍数 - 因此您的 Grapheme 对象在 32 位平台和 Hotspot JVM 上总共为 16 字节。任何指向 Grapheme 对象的指针都将占用额外的空间(每个可能 4 个字节)。对象本身不需要空间来存放自己的地址;该内存由其他东西拥有(例如,堆栈帧或另一个对象)。

于 2012-01-30T06:39:05.940 回答