【问题标题】:Where is "null" in memory内存中的“null”在哪里
【发布时间】:2011-11-14 20:59:40
【问题描述】:

在 java 中,不能在声明中声明数组的大小

int[5] scores;  //bad

有人告诉我这是因为 JVM 在初始化对象之前不会在内存中分配空间。 如果您有一个实例数组变量(使用默认值 null 自动初始化),该变量是否指向堆中指示 null 的位置?

【问题讨论】:

  • 0 ... 如 .... NULL (nothing, nada, zippo)
  • 你在糟糕的一天击中了 Harry Flugleman。

标签: java memory jvm initialization


【解决方案1】:

空引用实际上是一个零值。操作系统会阻止任何程序访问内存中的零地址,因此 JVM 会主动检查并确保引用值不为零,然后才允许您访问它。这让 JVM 给你一个很好的 NullPointerException 而不是“程序执行了非法操作”崩溃。

所以你可以说变量“指向”一个无效的堆位置。或者你可以说这个变量没有“指向”任何东西。在这一点上,这只是一个语义问题。

【讨论】:

  • 0 是否为有效内存地址取决于操作系统。
【解决方案2】:

不,因为在 JVM 中不需要这样做。 如果您使用的是本机语言(例如 C 和 C++),则 NULL 是一个具有零值的指针,它指向内存基地址。显然这不是一个有效的地址,但无论如何你“可以”取消引用它——尤其是在没有受保护内存的系统中,比如旧的 MS-DOS 或嵌入式处理器的小型系统。并不是说它是一个有效的地址——通常那个位置包含中断向量,你不应该接触它们。当然,在任何现代操作系统中都会引发保护错误。

但在 JVM 中,对对象的引用更像是句柄(即表中的索引),而 null 是一个“不可能”值(表域之外的索引),所以它可以t 被取消引用并且不占用此类表中的空间。

【讨论】:

  • 好的,那么 null 值只是保存在堆栈上的变量中吗?
  • 是的。 JVM 将检查何时(以及是否)它被取消引用,如果它为 null,则引发异常。
  • 也可以看看这个相关的问题,里面有很详细的回答:stackoverflow.com/questions/2707322/what-is-null-in-java
  • “显然这不是一个有效的地址”——这是不正确的。 0 是一个完全有效的内存地址。有许多计算平台地址 0 是有效的。 0 是否有效完全取决于硬件和软件 (OS)。
  • 我理解,但我是在所问问题的上下文中谈论的,其中我们正在处理指向对象(类实例)的指针。 C++ 类实例不能位于 0,因为空指针的全部目的是成为有效指针的“不可能”值,因此将其标记为无效/空/未初始化/等。
【解决方案3】:

我认为这篇文章会回答你的问题 - Java - Does null variable require space in memory

在 Java 中,null 只是一个引用的值(基本上是 受限指针)可以有。这意味着参考是指 没有什么。在这种情况下,您仍然会占用参考空间。 这是 32 位系统上的 4 个字节或 64 位系统上的 8 个字节。 但是,您不会为课程占用任何空间 引用指向,直到您实际分配该实例 将引用指向的类。

编辑:就字符串而言,Java 中的字符串需要 16 位(2 个字节) 对于每个字符,加上少量的簿记开销, 这可能是未记录的和特定于实现的。

(如果对你有帮助,记得点赞链接中的答案)

【讨论】:

    【解决方案4】:

    不...您将在对象的变量中有一个空 (0x00) 引用。

    【讨论】:

      【解决方案5】:

      我认为“int[5] scores; //bad”不是由于内存分配。 请注意,当您声明某些内容时,您实际上是在声明 类型参考名称 = 新类型() 通常。

      观察这两个例子 int[] 分数 = 新 int[5]; JLabel 标签 = 新的 JLabel();

      类型(左侧)为int[]和JLabel,与内存分配无关(指针除外),而新实例(右侧,需要分配内存)为int [5],需要 5 个 int 的空间,而 JLabel(),不需要参数来调用构造函数,但内存足够 JLabel 使用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-15
        • 1970-01-01
        • 2015-02-05
        • 1970-01-01
        相关资源
        最近更新 更多