java - 如果我对对象的引用超过 32 位所能解释的,会发生什么情况?

标签 java memory-management reference integer-overflow

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

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

如果我创建了超过 4,294,967,296 (232) 个对象类型的变量并尝试将它们分配给不同的对象,会发生什么情况?由于整数溢出,某些变量/引用会获得相同的内存地址吗?这意味着不可能在内存中引用超过 4,294,967,296 个对象?

最佳答案

So I just learned when you declare a variable of type Object ( i.e. Object a; ), a 32-bit space is allocated for that variable. Inside this variable/reference, there is a memory address to an actual Object.

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

因此,假设您实际上 的意思是“32 位 空间”,您所说的可能是正确的,也可能是错误的。对于 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 个字符,字符串 文字 限制为 2^16 个字符,等等。这些限制比 32 位和 64 位引用限制更基本。


跟进

So to make long stories short, there will always be a pre-determined wall no matter how much memory I force my operating system to dedicate to my program at compile time ?

没错。 (有点。您不能强制操作系统在编译时为您的程序分配内存。内存大小是在您启动程序时确定的,而不是在编译时它。)基本上,您可以在程序启动时转动以下“旋钮”:

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

  • -Xms 和 -Xmx 表示堆应该有多大......受可寻址能力和操作系统准备提供给 JVM 进程的内存量的约束。

    <
  • 还有一个Compressed OOPS与 64 位 JVM 相关的功能,但通常默认情况下处于启用状态。

关于java - 如果我对对象的引用超过 32 位所能解释的,会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17645959/

相关文章:

java - JPanel 不显示图形

c++ - 在 C++ 中返回对象

c# - OutOfMemoryException 何时发生?

c++ - 改进 malloc() 算法的下一步是什么?

java - 在 Scala 中实现 REPEAT UNTIL 时的 stackoverflow

java - GUI 添加了组件,但显示时显示空白

html - 如何用一个 css 表引用多个 html 页面?

Java:从计算的角度来看,如果将一个数组设置为对另一个数组的引用会怎样?

c++ - 通过引用传递对 lambda 的引用

java - 我的 swing 对话框在 Mac 和 Windows 上以不同的方式显示长字符串