【问题标题】:In terms of memory, what happens to a null variable in Kotlin?在内存方面,Kotlin 中的 null 变量会发生什么?
【发布时间】:2020-10-07 21:24:38
【问题描述】:

当我第一次学习编码时,有人告诉我“当你声明一个变量时,你会在内存中为该变量保留空间”,但是如果该变量在 Kotlin 中可以为空,那么该变量何时转换为 null 以释放其空间?

例如,我有一个可为空的字符串变量。

var x: String? = "Some text"

当我将x设置为null时,内存中的空间解放了吗?

x = null

我在 Kotlin 的页面中阅读了有关变量的信息,但它没有提及任何关于此的内容:

我了解from other reading,如果我没有对此变量的任何引用,那么 GC 将释放内存,但我有一个具有 null 值的变量。

【问题讨论】:

标签: variables kotlin garbage-collection garbage


【解决方案1】:

对象的变量总是占用 4 字节或 8 字节(取决于 VM 是 32 位还是 64 位),无论它设置为 null 还是其他任何值。一个原语的变量占用该原语的定义(浮点数和整数为 4 个字节,双精度数和长整数为 8 个字节等)。

因此,String 的声明保留了 4 个字节。当变量超出范围时,该内存将被回收。如果它是在函数内部声明的,那么当函数返回时,它就会超出范围。如果它被声明为具有支持字段的属性,那么当它所属的类实例被垃圾收集器回收时,它就会超出范围。 (请注意,一个属性可能根本没有支持字段,因此不需要为该属性的每个实例保留空间。)如果它在 object 或顶级空间中声明,则它永远不会超出范围,而应用程序正在运行。

不要将变量本身与它可以指向的对象混淆。这些将占用超过 4 个字节,并且大小当然会有所不同。它们的内存在它们被实例化时被保留,并且当它们不再被任何地方引用时被垃圾收集器回收(因此,如果您将对 ojbect 的最后引用设置为null确实会导致其内存被释放)。

【讨论】:

  • "如果它被声明为属性,当它所属的类实例被垃圾收集器回收时,它就会超出范围。(请注意,属性可能根本没有支持字段。 )" 我认为仅在有支持字段时才保留内存可能不够清楚。
  • @AlexeyRomanov,谢谢。我试着澄清一下。
  • 那么,如果变量有一个值在空间中增长,但如果是无效它的减少,如果设置另一个值再次增长?
  • 我不确定我是否完全理解您的要求。但重申一下,变量不是对象本身。它是一个指向内存地址的数字,所以它总是占用相同的空间。
【解决方案2】:

这里涉及两个独立的概念。

首先是变量的概念。正如@Tenfour04 解释的那样,所有对象变量都需要 4 或 8 个字节(32 或 64 位 JVM)。此空间用于存储对象的引用

第二个是对象本身。在您的示例中,您使用“某些文本”实例化 String 类的实例。该对象将包含一个char 原语数组,它们是字符串中的各个字符('S'、'o'、'm' 等)。当 String 被实例化时,堆中的空间将由JVM。

虽然您的变量包含对“某些文本”字符串对象的引用,但 GC 不会采取任何行动。当您的应用程序代码不再有对该对象的任何引用时,它就有资格进行垃圾回收(尽管没有确切定义何时会发生这种情况)。

同样,在您的示例中,当您将变量 x 设置为 null 时,您将删除引用,并且“某些文本”对象将符合收集条件。

通常,不需要显式地为空引用,GC 非常擅长查找不再引用的对象。与其使用显式的 null 赋值,不如查看变量的范围。一旦变量超出范围,它就不再被使用,因此它对对象的引用也不再被使用。范围可以是函数/方法或代码块等。

【讨论】:

    猜你喜欢
    • 2018-04-08
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2015-05-25
    相关资源
    最近更新 更多