JVM 是否可以优化引用 null(null 类型的实例)所需的内存?
大家下午好,
我有一堂课,如下所示:
public class Grapheme {
public Grapheme(int[] code_points) {
this.code_points = code_points;
}
int[] code_points;
}
来自 链接由 bdonlan 下面提供,我知道通常 Grapheme 对象需要 8 个字节对象头,4 个字节的变量 code_points
(其类型为引用),以及 4 个字节的填充。
因此,如果我使用代码 new Grapheme(null)
创建 Grapheme 实例,该 Grapheme 实例通常总共需要 16 个字节。由于是否为 16 字节是特定于实现的,因此从这里开始我将 这个数字 称为 x 字节。
基本上我想知道是否创建 n 个字形,将 null
传递给所有这些字形的构造函数 Grapheme(int[])
,并且将这些 Grapheme 存储到长度为 n 的数组中,
运行时(存储 Grapheme 实例)所需的总内存是否严格 n * x 字节?
或者 JVM 是否有有机会尝试进行一些神奇的优化,使所需的内存低于 n * x 字节?
Good afternoon all,
I have a class which looks like this:
public class Grapheme {
public Grapheme(int[] code_points) {
this.code_points = code_points;
}
int[] code_points;
}
From the link provided by bdonlan below, I understand that typically a Grapheme object would require 8 bytes for object header, 4 bytes for the variable code_points
(whose type is reference), and 4 bytes of padding.
So if I create an instance of Grapheme using the code new Grapheme(null)
, that instance of Grapheme would typically require a total of 16 bytes. Since whether or not it is 16 bytes is implementation specific, from here on I'll refer to this number as x bytes.
Basically I was wondering if I create n number of Graphemes, passing null
into the constructor Grapheme(int[])
for all of them, and store those Graphemes into an array of length n,
Will the total memory required by the runtime (to store the Grapheme instances) be strictly n * x bytes?
Or is there any chance that the JVM could try and do some magic optimizations such that the memory required is below n * x bytes ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,物体的大小是固定的。考虑一下 - 如果 JVM 确实将您的 Graphemes 打包到一个数组中,它们之间没有空格,如果稍后某些代码更改了
code_points
的值,会发生什么?它必须移动所有其他字形,并重写指向其中任何一个的指针。这将对性能造成巨大影响(您可能需要执行完整的 GC 来重写所有这些指针...),并且对于试图弄清楚为什么简单的赋值如此缓慢的程序员来说是完全难以理解的。因此 JVM 不会进行此类优化。另请注意,您的开销估计有点偏差。根据 this page,对象的开销为 8 个字节,加上用于任何内部字段,12 字节。然后将其向上舍入为 8 字节的倍数 - 因此,这里的 Grapheme 对象在 32 位平台和 Hotspot JVM 上总共为 16 字节。任何指向 Grapheme 对象的指针都将占用额外的空间(每个指针可能需要 4 个字节)。对象本身不需要空间来存放自己的地址;该内存由其他东西(例如,堆栈帧或另一个对象)拥有。
No. The size of an object is fixed. Consider - if the JVM did pack your Graphemes into an array with no space between them, what happens if some code changes the value of
code_points
later? It'd have to move all the other Graphemes around, and rewrite any pointers to any of them. This would be a HUGE performance hit (you'd probably need to perform a full GC to rewrite all those pointers...), and be totally inscrutable to the programmer trying to figure out why a simple assignment was so slow. So the JVM does no optimizations of this sort.Also note that your overhead estimates are a bit off. According to this page, objects have an overhead of 8 bytes, plus the space for any internal fields, for 12 bytes. This is then rounded up to a multiple of 8 bytes - so your Grapheme object here would be 16 bytes in total on a 32-bit platform and the Hotspot JVM. Any pointers to the Grapheme object will take additional space (probably 4 bytes each). Objects do not need space for their own address per se; that memory is owned by something else (eg, a stack frame, or another object).