大家下午好
我有一堂课,看起来像这样:
public class Grapheme {
public Grapheme(int[] code_points) {
this.code_points = code_points;
}
int[] code_points;
}
从bdonlan link提供的below中,我了解到一个Grapheme对象通常需要8个字节的对象标头,4个字节的变量
code_points
(其类型为引用)和4个字节的填充。因此,如果我使用代码
new Grapheme(null)
创建Grapheme实例,则该Grapheme实例通常需要总共16个字节。由于是否为16字节是特定于实现的,因此从这里开始,我将此数字称为x字节。基本上,我想知道是否创建n个Graphemes,将所有元素的
null
传递给构造函数Grapheme(int[])
,并将这些Graphemes存储到长度为n的数组中,运行时(用于存储Grapheme实例)所需的总内存是否严格为n * x字节?
还是JVM有机会尝试做一些魔术优化,使所需的内存低于n * x字节?
最佳答案
否。对象的大小是固定的。考虑-如果JVM确实将您的Graphemes打包成一个数组,并且它们之间没有空格,那么如果某些代码稍后更改code_points
的值会发生什么呢?它必须四处移动所有其他的Graphemes,并重写指向其中任何一个的任何指针。这将对性能产生巨大的影响(您可能需要执行完整的GC来重写所有这些指针...),并且对于试图弄清为什么简单的分配如此缓慢的程序员,这是完全不可理解的。因此,JVM不会进行此类优化。
另请注意,您的间接费用估算有些偏差。根据this page,对象的开销为8个字节,加上任何内部字段的空间为12个字节。然后将其舍入为8字节的倍数-因此,在32位平台和Hotspot JVM上,这里的Grapheme对象总共为16字节。任何指向Grapheme对象的指针都将占用额外的空间(每个指针可能大约4个字节)。对象本身不需要空间来存放其自身的地址。该内存由其他东西拥有(例如,堆栈框架或其他对象)。