如果我对对象的引用多于 32 位所能容纳的数量,会发生什么情况?

2024-02-19

所以我刚刚了解到当你声明一个 Object 类型的变量时(即Object a;),为该变量分配 32 位空间。在这个变量/引用内部,有一个实际对象的内存地址。

现在假设我有足够大的内存来执行此操作。

What would happen if I created more than 4,294,967,296 (232) variables of type Object and tried assigning them to a distinct Object? Would some variables/references get the same memory addresses due to integer overflow? Meaning it's impossible to have references to more than 4,294,967,296 Objects in memory?


所以我刚刚了解到,当您声明一个 Object 类型的变量(即 Object a; )时,会为该变量分配一个 32 位空间。在这个变量/引用内部,有一个实际对象的内存地址。

(当您谈论“32 位空间”时,IT 人员会立即认为您指的是address空间...并且 32 位地址空间为您提供 2^32 字节的存储空间!!)

所以假设你actually意思是“32位ofspace” 你所说的可能是对的,也可能是错误的。对于 32 位 JVM,引用确实是 32 位长,这意味着你的程序(理论上)最多可以引用 2^32 个不同的对象,任何类型。即使表示 2^32 个不同的(32 位)引用也将占用 2^34 个字节。

另一方面,如果您在 64 位 JVM 上运行程序,则引用的大小为 64 位,这意味着您的程序(理论上)最多可以引用 2^64 个不同的对象。

但这都是理论上的。问题是在 32 位机器上,您的程序没有足够的内存来表示那么多不同的对象。 32 位机器上的最小 Java 对象占用(至少)8 个字节。因此,即使您拥有整个可用地址空间,您也只能表示 2^29 个对象。实际上,操作系统不会为 JVM 提供那么多内存。事实上,根据操作系统的不同,它最多可以获得 4Gb 地址空间中的 2 到 3Gb。


当然,如果您运行 64 位 JVM(在 64 位操作系统/和支持 64 位的硬件上),您就有更大的空间用于对象引用,并且可以有更多的内存来表示它们。但由于硬件限制,您最终仍然会“碰壁”。

值得注意的是,Java 还有其他各种固有的限制。例如,数组最多可以有 2^31 个元素,字符串最多可以有 2^31 个字符,字符串literals限制为 2^16 个字符,依此类推。这些限制比 32 与 64 位参考限制更为基本。


FOLLOWUP

因此,长话短说,无论我在编译时强制操作系统将多少内存专用于我的程序,总会有一堵预先确定的墙?

那是对的。 (有点。你不能强迫操作系统将内存专用于你的程序编译时间。内存大小是在您确定时确定的launch程序,而不是编译它时。)基本上,在程序启动时,您有以下“旋钮”需要旋转:

  • JVM(32 位与 64 位)对可寻址的内存量进行了限制,并确定引用是 32 位还是 64 位。 (请注意,这是一个运行时选择。32 位和 64 位编译的字节码文件是相同的。)

  • -Xms 和 -Xmx 表示堆应该有多大……受到可寻址性和操作系统准备提供给 JVM 进程的内存量的限制。

  • 还有一个压缩面向对象 http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop与 64 位 JVM 相关的功能,但通常默认情况下处于启用状态。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果我对对象的引用多于 32 位所能容纳的数量,会发生什么情况? 的相关文章

随机推荐